前言
在Java并发编程中,CountDownLatch是一个简单易用但又功能强大的同步工具类。它可以理解为一个“倒计时门闩”,允许一个或多个线程等待其他线程完成操作后再继续执行。
什么是CountDownLatch(倒计时)
CountDownLatch
允许 count
个线程阻塞在一个地方,直至所有线程的任务都执行完毕。
CountDownLatch
是一次性的,计数器的值只能在构造方法中初始化一次,之后没有任何机制再次对其设置值,当 CountDownLatch
使用完毕后,它不能再次被使用。
CountDownLatch原理
CountDownLatch
是共享锁的一种实现,它默认构造 AQS 的 state
值为 count
。这个我们通过 CountDownLatch
的构造方法即可看出
public CountDownLatch(int count) {
if (count < 0) throw new IllegalArgumentException("count < 0");
this.sync = new Sync(count);
}
private static final class Sync extends AbstractQueuedSynchronizer {
Sync(int count) {
setState(count);
}
//...
}
当线程调用 countDown()
时,其实使用了tryReleaseShared
方法以 CAS 的操作(原子操作)来减少 state
,直至 state
为 0 。当 state
为 0 时,表示所有的线程都调用了 countDown
方法,那么在 CountDownLatch
上等待的线程就会被唤醒并继续执行。
/**
* Decrements the count of the latch, releasing all waiting threads if
* the count reaches zero.(count-1,如果 count=0 则释放所有等待的线程)
*
* <p>If the current count is greater than zero then it is decremented.
* If the new count is zero then all waiting threads are re-enabled for
* thread scheduling purposes.(如果当前的 count>0 则 count-1,如果当 count到 0 的时候则重启所有等待的线程)
*
* <p>If the current count equals zero then nothing happens.(如果当前的count=0则无事发生)
*/
public void countDown() {
sync.releaseShared(1);
}
releaseShared
方法是 AbstractQueuedSynchronizer
中的默认实现。关于共享模式的释放资源操作,改天出一期单独讲。
// 释放共享锁
// 如果 tryReleaseShared 返回 true,就唤醒等待队列中的一个或多个线程。
public final boolean releaseShared(int arg) {
//释放共享锁
if (tryReleaseShared(arg)) {
//释放当前节点的后置等待节点
doReleaseShared();
<