1、What is CountDownLatch?
CountDownLatch提供了一种同步机制,可以允许一个或多个线程等待,直到其他线程上的一系列操作完成后,那个等待的线程再携手和其他线程继续走下去。用一句话大白话就是:我等你们,你们上完厕所,我再和你们一块出发。像这样的需求在java 中怎么实现呢?就需要使用CountDownLatch
。
要想学会使用CountDownLatch,只要搞清楚下面三个点,就可以了:
1、指定一个count。比如:CountDownLatch startSignal = new CountDownLatch(1);// 开始执行信号
2、明白await()
方法。当count变为0的时候就继续往下执行,没到0就一直卡着。
3、明白countDown()
方法。这个方法负责递减,每次减1。
概念简单的说一说,talk is cheap,还是上代码。
2、When should we use CountDownLatch ?
Use CountDownLatch when one of Thread like main thread, require to wait for one or more thread to complete, before its start doing processing.
当我们希望在main线程里,必须等待其他子线程执行完以后继续往下执行。这个时候,我们就需要用到CountDownLatch
。
按照上面的需求,在你不知道CountDownLatch之前,你也许会这样写你的代码:
我们希望输出这样的结果:
然而真正的输出结果是这样的:
使用了CountDownLatch后,像下面这样:
输出结果是一个顺序的,与主线程同步的状态:
3、How CountDownLatch works ?
现在我们来一步步复盘CountDownLatch执行顺序。
1、首先我们定义了CountDownLatch doneSignal = new CountDownLatch(N);
。完成信号。
2、然后我们定义了CountDownLatch startSignal = new CountDownLatch(1);
。开始信号。
3、然后我们使用for
循环来启动10个线程。我们分别把完成信号和开始信号传入线程。像这样:
for (int i = 1; i <= N; i++) { new Thread(new Worker(i,doneSignal, startSignal)).start();// 线程启动了
}
4、线程按理说已经开始执行了。然而,我们发现在Work
类中的run
方法里有这样一句话:
startSignal.await(); // 等待开始执行信号的发布
这句话导致了我们之前启动的10个线程全都处于等待状态,他们正在等待发号施令。那么这些阻塞的线程,什么时候开始运行呢? 根据前面我们说的,当count=0的时候就开始继续往下执行了。所以你也许知道下一步怎么触发他们了。 万事俱备,只欠东风!
5、给东风呗,让10个线程run起来了,没错,通过一句话就可以了:
startSignal.countDown();// 开始执行啦
我们通过countDown()
方法把count变为了0,这时候10个线程就跑起来了。 自然每个线程执行完都必须要--1啊,就是要调用完成信号的countDown()
方法。
6、就这样,当10个线程运行完以后,由于每个线程执行完都会对count减1。自然10个线程执行完以后,doneSignal
的count就为0。 我们知道,当count为0时,之前一直await的main线程,也就是主线程就继续往下执行了。
main线程的代码:
本文分享自 ImportSource 微信公众号,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文参与 腾讯云自媒体同步曝光计划 ,欢迎热爱写作的你一起参与!