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("材料都准备好了,那就开始建房子吧");
}
}