CountDownLatch 用于“等别人做完再走”,适合启动器-工作者模型,一次性使用;CyclicBarrier 用于“大家一起到齐才一起走”,支持多轮对等协作,可重用且带回调。

CountDownLatch 和 CyclicBarrier 都是 Java 并发包中用于线程协调的工具,但设计目标和行为逻辑完全不同:前者是“等别人做完再走”,后者是“大家一起到齐才一起走”。
等待逻辑不同:单向等待 vs 双向协同
CountDownLatch 的 await() 是主线程(或某几个线程)被动等待其他线程调用 countDown() 把计数器减到 0;而 CyclicBarrier 的 await() 是所有参与线程主动到达后互相等待——第 N 个线程调用 await() 的瞬间,所有 N 个线程才同时被唤醒。
- CountDownLatch:适合“启动器-工作者”模型,比如主线程启动多个任务后统一汇总结果
- CyclicBarrier:适合“对等协作”模型,比如多线程分段计算后需要同步校验、每轮迭代前集体就绪
生命周期不同:一次性 vs 可重用
CountDownLatch 初始化后计数器只能递减,归零即永久失效;CyclicBarrier 在所有线程通过屏障后自动重置计数器,可重复使用多次。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- CountDownLatch 调用 await() 后若计数器已为 0,会立即返回,不阻塞
- CyclicBarrier 每次触发 barrierAction(可选回调)后,内部状态自动复位,下一轮 await() 仍有效
- 如果某个线程在 await() 时中断,CyclicBarrier 会打破当前代(generation),所有等待线程收到 BrokenBarrierException
底层实现与中断处理不同
CountDownLatch 基于 AQS 的共享锁模式,await() 可被中断,抛出 InterruptedException 后线程退出等待,但不会影响其他线程继续 countdown;CyclicBarrier 底层用 ReentrantLock + Condition 实现,await() 中断会破坏当前栅栏周期,触发 cleanup 并通知所有等待者。
立即学习“Java免费学习笔记(深入)”;
- CountDownLatch 不提供回调机制,仅靠计数归零释放等待线程
- CyclicBarrier 支持构造时传入 Runnable,在所有线程到达后、释放前执行一次(如数据合并、日志记录)
- CyclicBarrier 的 broken 状态需显式调用 reset() 恢复(但通常不建议,更推荐新建实例)
适用场景关键词对照
选错工具容易导致死锁或逻辑错乱。记住这几个典型信号:
- 要“等全部子任务结束”→ CountDownLatch
- 要“等所有人到齐再一起出发”→ CyclicBarrier
- 需要多轮同步(如模拟多轮游戏、迭代计算)→ CyclicBarrier
- 只做一次汇总或初始化检查 → CountDownLatch 更轻量

















