CountDownLatch
通过递减 AQS
同步状态 state
来实现闭锁的控制。
// CountDownLatch
public CountDownLatch(int count) {
if (count < 0) throw new IllegalArgumentException("count < 0");
this.sync = new Sync(count); // 构建同步器
}
// CountDownLatch.Sync
Sync(int count) {
setState(count);
}
// CountDownLatch
public void await() throws InterruptedException {
sync.acquireSharedInterruptibly(1);
}
await
方法调用响应中断的共享锁获取方法 acquireSharedInterruptibly
,最终会调用到自己实现的 tryAcquireShared
方法
// CountDownLatch.Sync
protected int tryAcquireShared(int acquires) {
return (getState() == 0) ? 1 : -1;
}
分析 tryAcquireShared
返回值,同步状态 state
为 0
返回 1
,代表获取锁成功,大于 0
返回 -1
代表获取锁失败,进行阻塞等待。countDown
方法通过递减 AQS
的同步状态 state
变量直到为 0
,然后唤醒被 await
方法阻塞的线程。
public void countDown() {
sync.releaseShared(1);
}
countDown
方法会调用释放共享锁 releaseShared
方法,进而调用自己重写的tryReleaseShared
方法,通过尝试设置 state
变量来释放共享锁。
// AbstractQueuedSynchronizer
public final boolean releaseShared(int arg) {
if (tryReleaseShared(arg)) {
doReleaseShared(); // 释放共享锁
return true;
}
return false;
}
// CountDownLatch.Sync
protected boolean tryReleaseShared(int releases) {
// 循环
for (;;) {
// state状态值为0说明已经释放锁,直接返回false无需再次执行唤醒操作
int c = getState();
if (c == 0)
return false;
int nextc = c-1; // state自减
// CAS设置state值
if (compareAndSetState(c, nextc))
return nextc == 0; // 判断state值是否等于为0,相等返回true执行共享锁释放操作
}
}