cyclicbarrier 的可重用性依赖 generation 和 count 协同机制:每轮完成时新建 generation 并重置 count 为 parties;broken 状态使当前代永久失效,需 reset() 显式恢复。

CyclicBarrier 的可重用性不是靠“自动清零”实现的,而是由一套精巧的状态隔离机制支撑——核心在于 Generation(代) 和 count 重置逻辑 的协同。它不依赖外部干预就能循环使用,但一旦出错,也必须靠明确操作才能恢复。
Generation 是状态隔离的关键
CyclicBarrier 内部用一个静态内部类 Generation 标记当前栅栏所处的“生命周期”。每个 Generation 只有一个字段:boolean broken,表示该代是否已被破坏。
- 初始化时创建第一个 Generation,
broken = false - 当所有线程到达(
count == 0),执行 barrierAction 后,调用nextGeneration()—— 这会新建一个 Generation 实例,相当于“翻篇”,进入下一代 - 所有后续 await() 都在新 Generation 上校验,旧的 broken 状态不会影响新轮次
count 归零后自动重置为初始值
构造时传入的 parties 值同时赋给 count 字段。每次线程调用 await(),都会对 count 做原子减一:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 若减到 0:触发释放、执行 barrierAction、调用
nextGeneration(),并把count重新设回parties - 这个重置发生在锁内且是原子操作,保证多线程下不会错乱
- 所以同一实例能自然支持第二轮、第三轮……只要没被破坏
broken 状态让重用变得“有条件”
Generation 的 broken 字段一旦变为 true,该代就永久失效:
- 中断、超时、异常未捕获都可能触发
breakBarrier(),将broken = true - 此后所有 await() 直接抛
BrokenBarrierException,不再等待或计数 - 除非显式调用
reset():它会唤醒所有等待线程,并新建 Generation + 重置 count
底层靠 ReentrantLock + Condition 实现阻塞与唤醒
所有关键操作(await、reset、nextGeneration)都在同一把 ReentrantLock 下执行:
- 等待线程调用
trip.await()进入条件队列 - 最后一个线程到达后,调用
trip.signalAll()唤醒全部 -
reset()也会触发signalAll(),确保中断等待中的线程










