countdownlatch用于等待操作完成且不可重用,cyclicbarrier用于多线程协同到达屏障点且可循环使用;前者基于倒计时机制,后者基于集合点机制,并支持回调和状态查询。

CountDownLatch 用于“等待一组操作完成”,不可重用;CyclicBarrier 用于“多线程协同到达某个屏障点”,可循环使用。
设计意图不同:一个等结束,一个等汇合
CountDownLatch 的核心是“倒计时”——初始化时指定一个正整数,每次调用 countDown() 减一,当计数归零,所有阻塞在 await() 的线程被唤醒。它模拟的是“某件事做完后通知别人”,比如主线程等所有子任务执行完毕再继续。
CyclicBarrier 的核心是“集合点”——初始化时指定参与线程数,每个线程调用 await() 后阻塞,直到第 N 个线程到达,全部线程才同时释放。它模拟的是“大家约好一起出发”,比如多个线程分头计算,都算完才统一汇总、再进入下一轮迭代。
复用性差异:Latch 一次性,Barrier 可循环
CountDownLatch 计数归零后,状态不可逆:await() 立即返回,countDown() 仍可调用但无实际效果。它不是为重复使用设计的。
CyclicBarrier 在所有线程通过一次后自动重置(除非显式调用 reset() 强制中断),支持多轮协作。例如在并行迭代算法中,每轮都需等待全部线程完成当前阶段,这时 CyclicBarrier 更自然。
- 若需要“只等一次”,选 CountDownLatch
- 若需要“反复同步多次”,选 CyclicBarrier
- 若某次 await 被中断或超时,CyclicBarrier 会进入破损状态(broken),后续调用直接抛 BrokenBarrierException,需手动 reset 恢复
额外能力对比
CountDownLatch 不支持回调,也不感知参与线程身份;CyclicBarrier 允许传入一个 Runnable,在最后到达的线程释放前执行(常用于汇总逻辑),且能通过 getParties() 和 getNumberWaiting() 查看当前状态。
两者都不保证线程执行顺序,但 CyclicBarrier 的“同时释放”语义更强调协作时序,而 CountDownLatch 更偏向单向依赖关系。
简单选择建议
想表达“我等你们干完”,用 CountDownLatch;
想表达“我们一起干,干完再一起往下走”,用 CyclicBarrier。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











