一、CountDownLatch类
CountDownLatch可以使一个线程在等待另外一个线程完成工作以后再继续执行;
使用倒计时计数器实现;
当每个线程成完成任务以后,计数器就会减一;
当计数器数值为0 的时候,表示当前线程已经完成任务,然后恢复至CountDownLatch上的等待线程来继续完成任务;
二、CountDownLatch的典型使用场景
1、启动一个服务时,主线程需要等待多个组件加载完毕以后再继续执行;
2、实现多个线程开始执行任务的最大并行性;注意是并行;
三、CountDownLatch的缺点
CountDownLatch是一次性的,计数器在构造方法中只能初始化一次,之后没有任何机制再次对其重置;
当CountDownLatch使用完毕后,它就不能再次被使用;
四,CountDownLatch方法说明
//递减锁计数器,达到0时,释放所有等待线程。
public void countDown() {
sync.releaseShared(1);
}
//当前线程在锁计数器倒计时为0之前一直处在等待状态
public void await() throws InterruptedException {
sync.acquireSharedInterruptibly(1);
}
//当前线程在锁计数器倒计时为0之前一直处在等待状态
//timeout等待时间
//unit时间单位
public boolean await(long timeout, TimeUnit unit)
throws InterruptedException {
return sync.tryAcquireSharedNanos(1, unit.toNanos(timeout));
}
五、栗子:主线程等到子线程执行完毕在执行
public static void main(String... args) {
final CountDownLatch countDownLatch = new CountDownLatch(3);
Thread threadA = new Thread(()->{
try {
System.out.println("主线程开始等待。。。");
//阻塞,等待countDown(),当countDown()=0就执行后面的线程
countDownLatch.await();
System.out.println("子线程执行完毕,主线程继续执行。。。");
} catch (InterruptedException e) {
}
});
Thread threadB = new Thread(() -> {
System.out.println("子线程开始执行。。。");
for (int i=3; i>0; i--){
System.out.println(i);
countDownLatch.countDown();//countDown减一
}
});
threadA.start();
threadB.start();
}