Runnable 结合 CountDownLatch # 实现线程结束开关

73 阅读1分钟

Runnable 结合 CountDownLatch # 实现线程结束开关

开发过程中,通常会遇到分阶段执行的情况,需要等前面的线程全部执行完毕再执行后面的代码,可以使用多线程工具类CountDownLatch来统线程的执行情况。

代码示例

import java.util.Random;
import java.util.concurrent.CountDownLatch;

/**
 * 多个线程都全部执行完毕后,再往下执行
 */
public class BuildHourse {

    /**
     * 多线程工具类CountDownLatch的一个用法示例
     * @param args
     */
    public static void main(String[] args) {
        //执行多线程之前的代码,本例中就是建房子
        System.out.println("准备材料");
        System.out.println("=========== 可以理解为多线程之前 ===========");

        //总的线程数为5 (理解为需要5种材料)
        int threadNum = 5;

        //创建一个CountDownLatch类,构造入参线程数
        CountDownLatch countDownLatch = new CountDownLatch(threadNum);

        //创建5个线程,并发执行
        for (int i = 0; i < threadNum; i++) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    //10000以内的随机数,作为等待时间
                    int waitMillis = new Random().nextInt(10000);

                    try {
                        //模拟线程执行,耗费一定的时间(本例是10秒内)
                        Thread.sleep(waitMillis);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                    //线程执行完毕,报告结果
                    System.out.println(Thread.currentThread().getName() + "材料已准备好,所用毫秒数:" + waitMillis);

                    //CountDownLatch类计数减一
                    countDownLatch.countDown();
                }
            }).start();
        }

        try {
            /**下面这句代码,CountDownLatch就阻塞在这里了
            直到countDown()到0了(从构造入参的线程数开始减)
            **/
            countDownLatch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        //由于CountDownLatch发挥的作用,等到上面的5个线程都执行完毕了
        System.out.println("=========== 可以理解为多线程之后 ===========");
        System.out.println("材料都准备好了,那就开始建房子吧");
    }

}