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执行共享锁释放操作
}
}
CountDownLatch原理详解
本文深入解析了CountDownLatch的实现机制,包括其如何通过递减AQS的同步状态state来实现闭锁控制,以及await和countDown方法的具体工作流程。
161

被折叠的 条评论
为什么被折叠?



