实现主线程与子线程交替执行

本贴最后更新于 2250 天前,其中的信息可能已经时移世改

原题

子线程循环 10 次,接着主线程循环 100,接着又回到子线程循环 10 次,接着再回到主线程又循环 100,如此循环 50 次,请写出程序

实现

其实创建子线程本来只需要在 Main 函数内 new Thread 即可,但为了遵循阿里巴巴的编码规约,尝试使用了线程池来创建子线程。

实现线程工厂


import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.ThreadFactory;

/**
 * @author Saber
 */
public class MyThreadFactory implements ThreadFactory {

    /**
     * 计数器
     */
    private int counter;
    /**
     * 线程名
     */
    private String name;
    /**
     * 状态
     */
    private List<String> stats;

    MyThreadFactory(String name) {
        counter=0;
        this.name=name;
        stats=new ArrayList<>();
    }

    @Override
    public Thread newThread(Runnable r) {
        Thread thread=new Thread(r,name+"Thread"+counter);
        counter++;
        stats.add(String.format("Created thread %d with name %s on %s \n", thread.getId(), thread.getName(), new Date()));
        return thread;
    }

    public String getStats(){
        StringBuilder buffer = new StringBuilder();
        for (String stat : stats) {
            buffer.append(stat);
        }
        return buffer.toString();
    }
}

实现主线程与子线程的循环方法

这里将主线程与子线程的循环方法拿出来放到一个类中是为了共享 bShouldSub 信号量,以实现交替互斥执行


/**
 * @author Saber
 */
public class Business {
    /**这里相当于定义了控制该谁执行的一个信号灯*/
    private boolean bShouldSub = true;

    synchronized void mainThread(int i)
    {
        if(bShouldSub) {
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        for(int j=0;j<100;j++)
        {
            System.out.println(Thread.currentThread().getName() + ":i=" + i +",j=" + j);
        }
        bShouldSub = true;
        this.notify();

    }

    synchronized void subThread(int i)
    {
        if(!bShouldSub) {
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        for(int j=0;j<10;j++)
        {
            System.out.println(Thread.currentThread().getName() + ":i=" + i +",j=" + j);
        }
        bShouldSub = false;
        this.notify();
    }
}

实现主方法


import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * @author Saber
 */
public class ThreadTest {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        new ThreadTest().init();

    }

    private void init()
    {
        final Business business = new Business();
        MyThreadFactory myThreadFactory=new MyThreadFactory("子线程");
        ThreadPoolExecutor threadPoolExecutor=new ThreadPoolExecutor(
                4,
                10,
                200,
                TimeUnit.MILLISECONDS,
                new ArrayBlockingQueue<>(5),
                myThreadFactory);

        /*
          用线程池创建了一个子线程,来运行subThread方法,子线程的方法运行一次后把自己wait
          此时,mainThread的循环启动
          mainThread运行完一次后把自己wait
          subThread得bShouldSub锁,继续执行
          ...
         */
        threadPoolExecutor.execute(() -> {
            for(int i=0;i<50;i++)
            {
                business.subThread(i);
            }
        }
        );

        for(int i=0;i<50;i++)
        {
            business.mainThread(i);
        }
    }
}

  • B3log

    B3log 是一个开源组织,名字来源于“Bulletin Board Blog”缩写,目标是将独立博客与论坛结合,形成一种新的网络社区体验,详细请看 B3log 构思。目前 B3log 已经开源了多款产品:SymSoloVditor思源笔记

    1090 引用 • 3467 回帖 • 298 关注
  • Java

    Java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由 Sun Microsystems 公司于 1995 年 5 月推出的。Java 技术具有卓越的通用性、高效性、平台移植性和安全性。

    3165 引用 • 8206 回帖
  • 线程
    120 引用 • 111 回帖 • 3 关注

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...
  • javacheng

    上次阿里面试就被问道了这种主线程,子线程交替的问题

  • visus

    trollface trollface trollface trollface