CountDownLatch允许一个或多个线程等待其他线程完成操作。定义CountDownLatch的时候,需要传入一个正数来初始化计数器(虽然传入0也可以,但这样的话CountDownLatch没什么实际意义)。其countDown
方法用于递减计数器,await
方法会使当前线程阻塞,直到计数器递减为0。所以CountDownLatch常用于多个线程之间的协调工作。
CountDownLatch示例
假设我们现在有这样一个需求:
从数据库获取数据
对这批数据进行处理
保存这批数据
为了让程序执行效率更高,第2步中我们可以使用多线程来并行处理这批数据,大致过程如下所示:
1 | public class CountDownLatchTest { |
由于线程获取CPU时间片的不确定性,所以有可能数据还没有处理完毕,第3步就执行完了:
1 | 获取数据完毕 |
我们可以借助CountDownLatch解决这个问题:
1 | public class CountDownLatchTest { |
我们定义了一个CountDownLatch,计数器值为10,和数据量一致。然后在第2步中,当每个线程执行完毕的时候调用countDown
方法,让计数器减1。在第3步前调用await
方法让main线程阻塞等待,直到计数器被减为0。所以这就保证了只有当所有数据加工完毕才执行保存数据操作。
执行方法,程序输出如下所示:
1 | 获取数据完毕 |
await
有重载方法:await(long timeout, TimeUnit unit)
,设置最大等待时间,超过这个时间程序将继续执行不再被阻塞:
1 | public class CountDownLatchTest { |
输出如下:
1 | main线程执行完毕 |