cyclicbarrier 可重复使用,因其在所有线程到达后自动重置计数器并切换至新 generation,结合 reentrantlock 保障原子性、condition 实现精准等待唤醒,从而支持多轮同步。

因为 CyclicBarrier 在所有线程到达后会自动重置状态,且其内部用 ReentrantLock 保证计数安全、用 Condition 管理等待与唤醒,所以它天然支持多轮复用,不需要每次重新创建实例。
可重复使用的关键:自动重置与代(Generation)机制
CyclicBarrier 不是一次性工具。每当 parties 个线程全部调用 await(),屏障就“触发”——执行可选的 barrierAction,然后唤醒所有等待线程,并立即重置内部计数器 count = parties,同时切换到下一代(new Generation())。这个“重置动作”是自动发生的,无需手动干预。
这意味着同一实例可以立刻用于下一轮同步,比如:
- 第一轮:4 个线程汇总周报 → 到齐后执行“生成周报摘要” → 自动重置
- 第二轮:同 4 个线程汇总月报 → 再次调用
await()→ 继续协作
而 CountDownLatch 的计数器只能递减归零,无法恢复;CyclicBarrier 的“循环”正体现在这里。
底层驱动:ReentrantLock + Condition 的协作流程
CyclicBarrier 没有继承 AQS,而是封装了标准并发原语来实现线程协调:
-
ReentrantLock:保护对
count的修改,确保count--是原子操作,避免多线程竞争导致计数错误 -
Condition trip:线程调用
await()后,若未到齐(count != 0),就执行trip.await()进入等待队列;最后一个线程则调用trip.signalAll()唤醒全部 - Generation 对象:记录当前轮次状态(如是否 broken),防止上一轮中断影响下一轮;每轮成功通过后都会新建 Generation,隔离状态
整个过程集中在 dowait() 方法中:加锁 → 减 count → 判断是否为最后一位 → 是则执行 barrierAction 并 signalAll → 解锁 → 其他线程被唤醒后自动重试或返回。
和 CountDownLatch 的本质区别就在这里
CountDownLatch 是“单向门”:主线程等子任务完成(减计数),门开一次即废;CyclicBarrier 是“旋转门”:所有参与者互相等(加计数逻辑等效),门关上再打开,可无限循环。
它的可复用性不是靠外部包装,而是由 ReentrantLock 的精确控制力 + Condition 的精准唤醒能力 + Generation 的状态隔离共同保障的。











