cyclicbarrier 的“可重入”指同步状态的可循环复用,依托代(generation)机制实现周期隔离与自动归位,而非简单计数器重置;其核心是支持多轮协作式并发,每轮独立且平等,适配分阶段任务。

CyclicBarrier 的“可重入”不是指锁意义上的可重入(如 ReentrantLock),而是指同步状态的可循环复用——它不消耗、不单向递减,而是在每次屏障触发后自动归位,进入下一轮等待周期。这种设计哲学,是 JUC 中对“协作式多阶段并发”问题的精准抽象。
核心在于“代(Generation)机制”而非计数器重置
很多人误以为 CyclicBarrier 只是把 count 从 0 再设回 parties 就完事了。实际上,它的可重用性依赖一个隐式的 Generation 对象:
- 每次初始化时创建一个新 Generation,代表当前同步周期
- 当最后一个线程 await() 触发屏障,执行 barrierAction 后,立刻生成新 Generation,并重置 count
- 所有正在 await() 的线程会检查自己等待的是不是“当前代”,旧代中被中断或超时的线程不会干扰新代的计数逻辑
- 这种代际隔离,让 reset()、broken 状态、异常传播都具备清晰边界,避免状态污染
与 CountDownLatch 的单向性形成鲜明对比
CountDownLatch 是“发射倒计时”模型:count 一旦归零,状态不可逆,必须新建实例才能再用。它的哲学是事件驱动的一次性通知;而 CyclicBarrier 是“集合出发”模型:
- 它不关心“谁先来”,只保证“所有人齐了才走”
- 每轮都是平等的起始点,没有主从、没有先后责任绑定
- 天然适配分阶段任务(如 MapReduce 的 map → shuffle → reduce 各阶段内协同)
屏障动作(barrierAction)是可重入逻辑的关键延伸
Runnable barrierAction 不是附加功能,而是可重入哲学的体现:
- 它由最后一个到达的线程执行,但属于整个屏障周期,不是某个线程的私有行为
- 每次触发都执行一次,且总在释放其他线程之前——确保共享状态更新的原子可见性
- 比如汇总中间结果、刷新上下文、记录阶段耗时,这些操作随每轮自动发生,无需外部调度
可重入 ≠ 无状态,而是“有界可再生”
CyclicBarrier 不是无限兜底的工具。它的可重用性有明确前提:
- 所有参与线程必须按约定调用 await(),缺一不可
- 若某轮因中断、超时或 reset() 导致 broken,需显式处理(如捕获 BrokenBarrierException 后重建或恢复)
- 它不管理线程生命周期,只管理同步点;线程退出后不再计入下一轮,这点和“可重入锁”完全不同
所以它的可重入,是面向场景的稳健设计,不是泛泛的“能反复调用”。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











