countdownlatch 的核心是 aqs 的 state 字段作为计数器:构造时设 state 为 count;countdown() 通过 cas 减 1,仅减至 0 时唤醒所有等待线程;await() 仅读取 state 判断是否为 0 决定挂起;state 归零后不可重置。

CountDownLatch 的核心不是“倒计时”这个动作本身,而是 AQS 的 state 字段如何被当作计数器使用。所有行为——等待、释放、唤醒——都围绕 state 的读取、CAS 修改和状态判断展开。
构造时:count 直接设为 AQS 的 state
调用 new CountDownLatch(3) 时,内部会创建静态内部类 Sync(继承自 AbstractQueuedSynchronizer),并执行:
-
setState(count)—— 把传入的 3 直接写入 AQS 的state变量 - 此后整个生命周期中,
state就是那个“剩余等待数”
countDown():CAS 减 1,仅当减到 0 才触发唤醒
每次调用 countDown(),实际执行的是 sync.releaseShared(1),关键逻辑在 tryReleaseShared 中:
- 循环读取当前
state值(记为c) - 若
c == 0,直接返回false(已归零,无需再减) - 否则尝试 CAS 将
state从c改为c - 1 - 只有当新值恰好等于 0 时,才返回
true,从而触发doReleaseShared()唤醒所有等待线程
await():靠 tryAcquireShared 判断 state 是否为 0
await() 调用的是 acquireSharedInterruptibly(1),其是否阻塞取决于 tryAcquireShared 的返回值:
- 该方法只做一件事:
return (getState() == 0) ? 1 : -1; - 返回 1 → 获取成功,线程继续执行
- 返回 -1 → 获取失败,线程被封装为 Node 加入 AQS 同步队列,并调用
LockSupport.park()挂起 - 后续唤醒由
doReleaseShared()完成,它遍历同步队列,对每个处于 SIGNAL 状态的头节点调用unparkSuccessor()
关键提醒:state 是唯一真相
不需要记住“门闩”“倒计时”这些比喻,真正驱动一切的是:
-
state初始化即计数值 -
countDown()是原子减 1,但只在减到 0 时广播唤醒 -
await()不修改 state,只读取并决定是否挂起 - 没有“重置”或“重复使用”能力——state 归零后无法恢复,这是它与 CyclicBarrier 的根本区别
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











