本文最后更新于 814 天前,其中的信息可能已经有所发展或是发生改变。
有时候在开发中,可能会遇到需要启动多个子线程的情况,并且这时候我们需要等待所有子线程执行完毕才能继续向下。
Thread配合CountDownLatch使用,可以轻松达到上述效果。
CountDownLatch像是一个倒计时器,你可以为它设置一个初始值,每执行完一个子线程就让它减一。
当它的值减到0时,将继续执行下面的代码。
示例
下面来看一个简单的小例子:
ExecutorService executorService = new ThreadPoolExecutor(10,10,
1L, TimeUnit.SECONDS,
new LinkedBlockingQueue<>(3),
Executors.defaultThreadFactory(),
new ThreadPoolExecutor.AbortPolicy());
CountDownLatch countDownLatch = new CountDownLatch(10);
for (int i=0;i<10;i++) {
int finalI = i;
executorService.execute(() -> {
System.out.println("子线程" + finalI + "正在执行");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
countDownLatch.countDown();
});
}
try {
countDownLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("所有子线程执行完毕");
下面是控制台输出的内容:
22:21:10.920 10824-10966/cn.lovelycatv.minespacex I/System.out: 子线程0正在执行
22:21:10.920 10824-10967/cn.lovelycatv.minespacex I/System.out: 子线程1正在执行
22:21:10.921 10824-10968/cn.lovelycatv.minespacex I/System.out: 子线程2正在执行
22:21:10.921 10824-10969/cn.lovelycatv.minespacex I/System.out: 子线程3正在执行
22:21:10.921 10824-10970/cn.lovelycatv.minespacex I/System.out: 子线程4正在执行
22:21:10.921 10824-10971/cn.lovelycatv.minespacex I/System.out: 子线程5正在执行
22:21:10.921 10824-10974/cn.lovelycatv.minespacex I/System.out: 子线程7正在执行
22:21:10.921 10824-10973/cn.lovelycatv.minespacex I/System.out: 子线程6正在执行
22:21:10.922 10824-10975/cn.lovelycatv.minespacex I/System.out: 子线程8正在执行
22:21:10.922 10824-10976/cn.lovelycatv.minespacex I/System.out: 子线程9正在执行
22:21:13.923 10824-10824/cn.lovelycatv.minespacex I/System.out: 所有子线程执行完毕
看一下控制台输出信息的时间,确实是三秒钟左右执行完了所有线程,实际开发中以最慢的为准。
函数
public void await();
public boolean await(long timeout, TimeUnit unit);
public void countDown();
调用await的线程会被挂起,直到CountDownLatch的值为0,第二个await函数与无参的await相似,但你可以为它设置一个超时时间,超过一定时间计时器的值还不为0则继续执行。
countDown 可以让计时器的值减一。