cyclicbarrier 以“全员到齐”为前提,由最后到达线程主动触发屏障动作、重置状态并唤醒全体;其通过 generation 实现自动代际切换与复用,但不保证内存可见性。

CyclicBarrier 的执行机制不是靠“计数归零”被动放行,而是以“全员到齐”为硬性前提,由最后一个到达的线程主动触发屏障打开、执行收尾动作、重置状态并唤醒全体——整个过程被封装在一次 await() 调用中,线程无需关心内部轮次切换。
屏障点:所有线程必须抵达的同步边界
每个线程调用 await() 时,CyclicBarrier 内部计数器 count 减 1。只有当该值减至 0(即最后一线程到达),才满足“全员就位”条件。在此之前,其余线程会在 Condition.await() 中挂起,等待被唤醒。
- 未达终点的线程会释放锁并进入等待队列,不消耗 CPU
- 等待状态可被中断,抛出
InterruptedException - 若某线程在等待中被中断或超时,屏障立即标记为损坏(
generation.broken = true),其余等待线程将收到BrokenBarrierException
屏障动作:由最后一线程独占执行的收尾逻辑
若构造时传入 Runnable barrierCommand,它会在计数归零后、唤醒其他线程前,由最后一个调用 await() 的线程同步执行。这是唯一能安全读取所有线程阶段性结果的位置。
- 适合做聚合计算(如汇总各线程的局部统计值)
- 可用于集中校验(如检查所有线程初始化是否成功)
- 不建议在此执行耗时或阻塞操作,否则会拖慢整轮进度
代际管理:自动重置与轮次隔离的核心
CyclicBarrier 不靠手动 reset() 实现复用,而是通过 Generation 对象实现“代”的切换。每当屏障被触发,就会调用 nextGeneration():
- 创建新
Generation实例,broken = false - 重置
count = parties - 调用
trip.signalAll()唤醒所有等待线程 - 旧等待线程被唤醒后,发现已进入新代,继续执行后续逻辑
线程安全与变量可见性需额外保障
屏障本身只保证“到达顺序”和“唤醒时机”,不提供内存可见性保证。若线程间通过普通字段传递阶段结果,必须配合其他机制:
- 使用
volatile修饰共享状态字段 - 在屏障动作中读取的数据,应确保写入方已完成写操作(如用
final字段或显式同步块) - 推荐将阶段性结果封装在不可变对象中,通过方法参数或返回值传递











