CyclicBarrier 的核心是确保指定数量线程全部调用 await() 后才同步放行,关键在于结构设计、状态共享与异常兜底;需准确设定线程数、明确定义屏障点、合理使用 barrierAction、保障共享数据线程安全,并妥善处理 BrokenBarrierException 和 InterruptedException。

明确线程数量与屏障点位置
创建 CyclicBarrier 时必须准确传入参与协同的线程总数(parties),这个数不能动态变化,也不能漏掉某个工作线程。每个线程在逻辑上应有且仅有一个明确的屏障点,即调用 await() 的位置。例如:4 个计算线程处理不同数据块,每轮迭代结束后统一在此处等待。
用 barrierAction 做汇总或同步动作
构造时传入 Runnable 回调(barrierAction),它由最后一个到达的线程触发执行,适合做集中操作:
- 打印日志:“第3轮计算完成,开始汇总”
- 读取各线程写入的共享结果(如
AtomicInteger[]或ConcurrentHashMap)并合并 - 更新全局状态(如递增轮次计数器)
注意:barrierAction 中不要阻塞太久,否则会拖慢所有线程从 await() 返回的时间。
共享中间结果需线程安全
各线程无法直接交换局部结果,必须通过线程安全的容器提前写入:
立即学习“Java免费学习笔记(深入)”;
- 避免用普通数组或 ArrayList,改用
AtomicIntegerArray、ConcurrentLinkedQueue或带锁的ReentrantLock包裹的结构 - 推荐按线程索引写入,例如
results[ThreadID] = localSum,barrierAction 再遍历读取 - 若用
volatile变量,仅适用于简单标志位(如“是否完成”),不适用于数值累加
必须处理 BrokenBarrierException 和中断
只要有一个线程在 await 期间被中断,或调用 reset() 之前发生异常,屏障就会进入 broken 状态,后续所有 await 都立即抛出 BrokenBarrierException:
- 每个线程的 try-catch 必须捕获
BrokenBarrierException和InterruptedException - 遇到 BrokenBarrierException 后,通常应主动退出当前任务,避免继续执行错乱逻辑
- 必要时可调用
barrier.isBroken()检查状态,或用barrier.reset()手动恢复(但需确保无线程正在 await 中)


















