一种同步辅助,允许一个或多个线程等待,直到在其他线程中执行的一组操作完成。
CountDownLatch 是用给定的 count 初始化的。由于调用了countDown()方法,await 方法阻塞,直到当前计数为零,之后释放所有等待线程,并立即返回任何后续的 await 调用。这是一种一次性现象——计数无法重置。如果需要重置计数的版本,可以考虑使用CyclicBarrier。
CountDownLatch 是一种通用的同步工具,可以用于多种用途。count为1时初始化的CountDownLatch用作简单的 on/off 的 latch或gate:所有调用wait的线程都在gate处等待,直到调用countDown()的线程打开它。一个初始化为N的CountDownLatch可以用来让一个线程等待,直到N个线程完成某个动作,或者某个动作已经完成N次。
CountDownLatch的一个有用的特性是,它不需要调用倒计时的线程等待计数达到0才继续,它只是防止任何线程继续等待,直到所有线程都通过。
可以看出,CountDownLatch并无显式地继承什么接口或类。
CountDownLatch 的 state 并不是 AQS 的默认值 0,而是可赋值的,就是在 CountDownLatch 初始化时,count 就代表了 state 的初始化值
count 表示我们希望等待的线程数,可能是
和 ReentrantLock 一样,CountDownLatch类也存在一个内部同步器 Sync,继承了 AbstractQueuedSynchronizer
可以叫做等待,也可以称之为加锁。
造成当前线程等待,直到锁存器计数到零,除非线程被中断。
如果当前计数为零,则此方法立即返回。
如果当前线程数大于0,则当前线程将出于线程调度的目的而禁用,并处于睡眠状态,直到发生以下两种情况之一:
如果当前线程:
就会抛 InterruptedException,并清除当前线程的中断状态。
无参版 await 内部使用的是 acquireSharedInterruptibly 方法,实现在 AQS 中的 final 方法
如果当前线程数大于0,则当前线程将出于线程调度的目的而禁用,并处于休眠状态,直到发生以下三种情况之一:
如果计数为零,则该方法返回值true。
如果当前线程:
就会抛出InterruptedException,并清除当前线程的中断状态。
如果指定的等待时间过期,则返回false值。如果时间小于或等于0,则该方法根本不会等待。
获得锁时,state 的值不会发生变化,像 ReentrantLock 在获得锁时,会把 state + 1,但 CountDownLatch 不会
降低锁存器的计数,如果计数为 0,则释放所有等待的线程。
如果当前计数大于零,则递减。如果新计数为零,那么所有等待的线程都将重新启用,以便进行线程调度。
如果当前计数等于0,则什么也不会发生。
releaseShared 已经完全实现在 AQS
主要分成两步:
对 state 进行递减,直到 state 变成 0;当 state 递减为 0 时,才返回 true。
研究完 CountDownLatch 的源码,可知其底层结构仍然依赖了 AQS,对其线程所封装的结点是采用共享模式,而 ReentrantLock 是采用独占模式。可以仔细对比差异,深入理解研究。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。