cyclicbarrier通过“集体签到”实现同步:所有线程调用await()在屏障点阻塞,最后一个线程使计数器归零,触发屏障动作、唤醒全部线程并自动重置为新generation,支持多轮复用。

CyclicBarrier 的同步逻辑不是靠“等一个信号”,而是靠所有线程在同一个点上“集体签到”——谁先到谁等,最后一个人到,大家才一起出发。它不依赖外部触发,也不需要主线程额外管理,天然适合固定成员、多轮协作的场景。
屏障点:所有线程必须抵达的统一停靠站
每个线程执行到关键阶段末尾时,调用 await() 方法,就相当于在屏障点打卡。此时该线程会被阻塞,进入等待队列;只有当第 N 个线程(即最后一个)也调用 await(),计数器归零,屏障才被触发。
- 计数器初始值为构造时指定的 parties 数,每调用一次 await() 就减 1
- 未达阈值前,线程处于 Condition 等待状态,由 ReentrantLock 保障操作原子性
- 最后一个线程不仅完成“签到”,还承担唤醒全部等待线程 + 执行 barrierAction 的职责
自动重置:一轮结束,下一轮立即就绪
屏障被触发后,CyclicBarrier 不会失效,而是立刻重建新“代”(Generation),计数器恢复为原始 parties 值。这意味着同一实例可无缝用于下一轮协作,无需重建对象或手动 reset()。
一款AI工具,主要用于自动分析崩溃并修复错误。监控 Cloudflare D1 崩溃报告,进行去重和 Codex 5.3 High 分析,生成修复并创建...,适合需要提升相关任务效率的用户。
- 适用于固定线程池反复执行同类任务,比如每秒一批数据清洗 → 特征提取 → 上报
- 即使某轮因异常中断(抛出 BrokenBarrierException),也可主动调用 reset() 恢复状态
- 相比 CountDownLatch,省去频繁 new 实例的开销,降低 GC 压力
屏障动作:最后一人执行的协调任务
通过构造函数传入的 Runnable barrierAction,会在所有线程到达后、唤醒前由最后一个线程执行。这是做阶段收尾工作的理想位置。
- 常用于汇总各线程计算结果、校验全局状态、写入共享缓存或触发下一步流程
- 注意:该动作在单一线程中运行,不涉及并发,但需保证其本身不阻塞或抛异常,否则整个屏障将被破坏
- 若 barrierAction 抛出异常,所有等待线程将收到 BrokenBarrierException
变量可见性:屏障不替你管内存,你得自己兜底
CyclicBarrier 保证的是“执行时机同步”,不是“数据可见性”。各线程写入的局部变量,在屏障之后能否被其他线程安全读到,取决于你是否做了正确同步。
- 推荐使用 volatile 字段、Atomic 类型,或在屏障动作中通过锁保护共享变量读写
- 避免仅靠“await 之后就一定能读到最新值”这种直觉——JVM 内存模型不会自动刷新普通字段
- 若需跨阶段传递状态,建议配合 ThreadLocal 或显式同步机制,而非依赖屏障隐式保证










