CyclicBarrier 是 Java 并发包中可重复使用的线程协同同步工具,用于让固定数量的线程在屏障点互相等待直至全部到达后才共同继续执行,适用于多轮分阶段并行任务。

CyclicBarrier 是 Java 并发包中用于线程间协同等待的同步工具,核心作用是让一组固定数量的线程在某个“屏障点”互相等待,直到所有线程都到达,才一起继续执行。它最突出的特点是可重复使用——用完一次后无需重建,自动重置,适合多轮、分阶段的并行任务。
它解决什么问题
当你有一组线程各自做独立工作,但必须等所有人做完当前阶段,才能统一进入下一阶段时,CyclicBarrier 就派上用场了。比如:
- 4个线程分别处理数据分片,全部完成后再汇总结果
- 压力测试中,10个线程同时加载就绪,再一起发起请求
- 游戏匹配系统里,5名玩家准备完毕才开启对局
- 迭代式算法中,每轮计算后需要所有线程同步,再开始下一轮
关键机制靠什么实现
CyclicBarrier 内部基于 ReentrantLock + Condition 实现,不是 AQS 直接派生,但逻辑清晰可靠:
- count 计数器:初始值等于参与线程数(parties),每次调用 await() 减 1
- 屏障触发条件:count 减到 0,说明所有线程已到达,此时唤醒全部等待线程
- Generation(代)机制:每次触发后新建一个 Generation 对象,标记“这一轮已过”,避免旧等待被误唤醒;若中途被中断或超时,会标记 broken 状态
- barrierAction 回调:可选 Runnable,由最后一个到达的线程执行,常用于汇总、清理或启动下一阶段
怎么用才不容易出错
实际使用注意三点:
立即学习“Java免费学习笔记(深入)”;
- 构造时明确指定线程总数,比如 new CyclicBarrier(5),少一个 await 就永远卡住
- await() 必须在每个线程的工作逻辑中显式调用,且通常放在“本阶段完成之后、下一阶段开始之前”
- 务必捕获 BrokenBarrierException 和 InterruptedException:前者表示屏障已被破坏(如某线程中断),后者表示当前线程被中断,两种情况后 barrier 通常不可再用,需 reset() 或重建
- reset() 可强制重置屏障,但会唤醒所有等待线程并抛出 BrokenBarrierException —— 适合异常恢复场景,非日常推荐
和 CountDownLatch 有什么区别
别混淆这两个“计数型”工具:
- CountDownLatch 是“一次性门栓”:count 减到 0 后永远保持打开状态,不能重用;适合“一个线程等多个线程完成”
- CyclicBarrier 是“旋转门”:每轮清零重计,支持多轮协作;适合“多个线程彼此等待”
- CountDownLatch 的 count 由其他线程调用 countDown() 减,CyclicBarrier 的 count 由每个线程调用 await() 自减
- CyclicBarrier 支持到达后的回调(barrierAction),CountDownLatch 不直接提供该能力
基本上就这些。用对场景、配好数量、记得异常处理,CyclicBarrier 就是个安静又可靠的协作伙伴。










