一、使用场景
CountDownLatch也属于JUC。线程可以使用await()进行等待,多线程进行递减计数,等到计数到0的时候等待即不再阻塞,从而向下执行。 在日常开发中经常会遇到需要在主线程中开启多个线程去并行执行任务,并且主线程需要等待所有子线程执行完毕后再进行汇总的场景。
二、使用
先介绍一些主要的方法:
void countDown():计数器减一
long getCount():返回当前计数值
void await():当前线程阻塞,直到计数器减到0才继续向下执行
boolean await(long timeout, TimeUnit unit) :与上述await()类似,只不过可以设置等待时间,如果在规定时间内计数器的值依然大于0,则继续执行
三、实例及讲解:
public class Demo {
// 创建一个CountDownLatch实例
private static volatile java.util.concurrent.CountDownLatch countDownLatch = new CountDownLatch(2);
public static void main(String[] args) throws InterruptedException {
Thread threadOne = new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(1000);
System.out.println("子线程1结束!");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
countDownLatch.countDown();
}
}
});
Thread threadTwo = new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(1000);
System.out.println("子线程2结束!");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
countDownLatch.countDown();
}
}
});
// 启动子线程
threadOne.start();
threadTwo.start();
System.out.println("等待所有子线程结束---");
// 等待子线程执行完毕,返回
countDownLatch.await();
System.out.println("所有子线程结束!");
}
}
测试结果:
等待所有子线程结束---
子线程2结束!
子线程1结束!
所有子线程结束!
四、总结:
简单来说,CountDownLatch是一个同步的辅助类,允许一个或多个线程一直等待,直到其它线程完成它们的操作。
这里就涉及两个问题: 1.如何让一个或多个线程一直等待;
2.如何让这些线程知道其它线程已经完成它们的操作
这两个问题主要是使用一个count的属性解决。使用count初始化CountDownLatch,然后需要等待的线程调用await方法。await方法会一直受阻塞直到count=0。 而其它线程完成自己的操作后,调用countDown()使计数器count减1。当count减到0时,所有在等待的线程均会被释放,并且count无法被重置。