countdownlatch基于aqs共享模式,state不可重置,适用于单次事件等待;cyclicbarrier基于reentrantlock+condition,支持重置与动态操作,适用于多轮协作同步。

CountDownLatch 和 CyclicBarrier 虽然都用于线程同步,但底层实现机制完全不同,这直接决定了它们的行为差异和适用边界。
CountDownLatch 基于 AQS 共享模式
它内部使用 AbstractQueuedSynchronizer(AQS)的共享锁模式,核心是 state 变量作为计数器:
- 初始化时,state 被设为线程数量(如 new CountDownLatch(3) → state = 3);
- 每次调用 countDown(),通过 CAS 原子递减 state;
- await() 方法会检查 state 是否为 0,不为 0 就进入 AQS 的共享等待队列挂起;
- 一旦 state 减至 0,所有阻塞线程被唤醒,且 state 永远保持为 0 —— 这就是它不可重置的根本原因;
- 没有锁竞争逻辑,也不涉及条件变量,纯靠 state + AQS 共享语义驱动。
CyclicBarrier 基于 ReentrantLock + Condition
它不依赖 AQS 的 state 字段,而是封装了一个 ReentrantLock 和一个 Condition 对象来管理等待队列:
Java JDK 25 来自 OpenJDK 官方归档,版本为 JDK 25,本条下载地址已指向官方 Windows x64 zip 安装包直链,适合调试旧项目或兼容旧版 Java 运行环境。
- 每个 await() 调用先获取锁,再判断是否达到 parties 数量;
- 未满时,线程在 Condition 上 await() 挂起,释放锁并进入等待队列;
- 最后一个线程到达时,触发 Condition.signalAll(),唤醒所有等待者;
- 唤醒后,屏障自动重置(内部计数器归零),支持下一轮使用;
- 可选的 barrierAction 在最后一线程释放前执行,由持有锁的线程串行调用。
关键差异直击本质
两者根本不是“同类工具的不同配置”,而是不同同步范式下的产物:
- CountDownLatch 是“事件驱动型”:关注“某件事是否完成”,适合单次等待场景;
- CyclicBarrier 是“协作驱动型”:关注“所有人是否就位”,本质是线程间协商同步点;
- AQS 共享模式天然适合一次性状态流转,而 ReentrantLock + Condition 更适合需要反复挂起/唤醒的协作模型;
- 所以 CyclicBarrier 支持 reset()、getNumberWaiting() 等动态操作,CountDownLatch 则连 reset() 方法都没有。
异常处理机制也不同
这对实际编码影响很大:
- CountDownLatch.await() 只抛 InterruptedException,中断后线程直接退出等待;
- CyclicBarrier.await() 会抛 BrokenBarrierException(当某线程中断或超时导致屏障被破坏时),所有等待线程都会收到该异常,确保状态一致;
- 这种设计让 CyclicBarrier 更适合强一致性要求的多阶段协同任务。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










