CyclicBarrier 是实现多线程同步启动的最直接方式,需指定参与线程数并调用 await(),支持可重用、超时控制及前置协调动作 barrierAction。

要让多个线程真正“一起开始”执行某项任务,CyclicBarrier 是最直接、最自然的选择。它不依赖外部调度或时间对齐,而是基于线程到达行为本身完成同步启动——所有线程调用 await() 后阻塞,直到最后一个线程抵达,屏障解除,全体同时继续。
明确参与方数量与屏障动作
构造 CyclicBarrier 时必须指定参与线程数(parties),这是同步启动的前提条件。若实际启动的线程少于该数值,其余线程将永久阻塞;多于该数则多余线程无法被屏障识别。可选的 barrierAction 是启动前的统一准备动作,比如初始化共享资源、打印启动信号、重置计时器等,由最后一个到达的线程执行,确保动作只发生一次且在所有线程就绪之后、执行之前。
- 使用
CyclicBarrier(int parties)适用于只需“齐发”无额外操作的场景 - 使用
CyclicBarrier(int parties, Runnable barrierAction)适合需要前置协调逻辑的情况,例如记录启动时刻、清空缓存、校验前置状态
每个线程执行路径需一致包含 await()
所有参与协同的线程,必须在关键启动点调用 barrier.await()。这一调用是阻塞点,也是同步点。调用后线程进入等待状态,不消耗 CPU,也不推进后续逻辑,直到全部线程都抵达此处。
- 避免在 await() 前做耗时操作(如长循环、I/O 等),否则会拉长整体等待时间
- 确保 await() 调用位于逻辑起点之后、核心任务之前,例如:准备完毕 → await() → 执行任务
- 必须捕获
InterruptedException和BrokenBarrierException,前者表示线程被中断,后者表示屏障已被破坏(如某线程 await 时异常退出)
利用可重用性支持多轮同步启动
CyclicBarrier 的“循环”特性意味着它在所有线程通过后自动重置,无需重新创建对象即可用于下一轮协同。这特别适合周期性任务,比如每秒一批数据处理、每帧游戏逻辑更新、多次性能压测等。
- 一轮结束后,所有线程从 await() 返回,可立即进入下一轮准备 → await() → 执行的循环
- 若某轮中发生异常导致屏障断裂(broken),需调用
reset()恢复,或检查isBroken()避免后续调用失败 - 注意:reset() 是强制重置,会唤醒所有等待线程并抛出 BrokenBarrierException,应谨慎使用
配合线程池与共享状态提升实用性
实际项目中,通常搭配 ExecutorService 管理线程生命周期,并借助线程安全结构传递启动上下文。例如,主线程预设任务参数,各工作线程在 await() 前读取;或 barrierAction 中统一分发批次 ID、时间戳等元信息。
- 避免在 barrierAction 中执行长时间操作,否则会拖慢所有线程的启动时机
- 共享变量推荐使用
AtomicInteger、ConcurrentHashMap或volatile字段,确保可见性与安全性 - 可结合
await(long timeout, TimeUnit unit)设置超时,防止因个别线程卡死导致整体挂起

















