扫描下方二维码或者微信搜索公众号
菜鸟飞呀飞
,即可关注微信公众号,阅读更多Spring源码分析
和Java并发编程
文章。
简介
- CountDownLatch是JUC包下提供的一个工具类,它的作用是让一个或者一组线程等待其他线程执行完成后,自己再接着执行。从命名上可以猜出,它是通过倒着计数,最后打开门闩这把锁,即每一个线程忙完自己的工作后,让计数器递减一次,当计数器递减到0时,锁(门闩)被打开,主线程(或者等待的线程)接着执行自己的工作。
- 在实际工作中,我们可能会遇到需要利用多线程来处理问题的同时,还需要控制这些线程的执行顺序,这个时候我们可以选择使用Thread类中提供的join()方法,也可以使用今天即将介绍的CountDownLatch来解决,还可以使用JUC包下的另一个类CyclicBarrier来解决。
如何使用
- CountDownLatch的使用十分简单,它只有一个构造方法,在构造方法中需要传入一个int类型的参数,这个参数就是用来控制CountDownLatch需要递减多少次才释放锁(打开门闩)。CountDownLatch还提供了以下三个方法,详细信息见下表。
方法名 | 方法作用 |
---|---|
void await() | 让调用该方法的线程阻塞,当CountDownLatch的计数器减为0时,才会让线程解阻塞 |
boolean await(long timeout, TimeUnit unit) | 让调用该方法的线程超时阻塞,如果超过了指定的时间,CountDownLatch的计数器还没有减为0,那么线程就会直接返回 |
void countDown() | 让CountDownLatch的计数器减1,当计数器的值减为0时,会让阻塞在CountDownLatch的线程解阻塞 |
- 下面以一个简单的场景,简单介绍下CountDownLatch的用法。在学生时代,总会有各种各样的考试,每次考完试,各科老师都会进行阅卷,计算总分,总分排名。在这个过程中,各科的阅卷是同时进行的,由于每一科老师的阅卷速度不一样,因此计算总分和总分排名的人需要等到所有老师阅卷完成后才能进行。这个时候我们可以用CountDownLatch这个工具类在程序中进行模拟一下这个场景。把每一科的老师当做一个线程,由于每一科老师的阅卷速度不一样,因此采用让线程随机休眠一段时间,当每一科的老师阅卷完成后,就调用CountDownLatch的countDown()方法让计数器减一,在主线程中调用CountDownLatch的await()的方法,目的为了让主线程等待所有老师阅卷完成,当所有老师阅卷完成时,计数器就减为0了,主线程就会从await()方法处解阻塞,然后进行总分加和,排名等工作。示例的Demo如下。
public class CountDownLatchDemo {
public static void main(String[] args) {
CountDownLatch countDownLatch = new CountDownLatch(6);
List<String> teachers = Arrays.asList("语文老师","数学老师","英语老师","物理老师","化学老师","生物老师");
Random random = new Random();
// 创建6个线程,模拟6个科目的老师同时开始阅卷
List<Thread> threads = new ArrayList<>(6);
for (int i = 0; i <</