CyclicBarrier仅控制线程执行时机,不保证资源线程安全;需在屏障前用volatile/AtomicInteger/synchronized确保写可见,在barrierAction中串行聚合,在await返回后安全读取或加锁修改。

CyclicBarrier 本身不负责资源的线程安全,它只控制执行时机——让所有线程在某个点“停住”,等齐了再一起往下走。真正要保证资源同步,得靠你在线程到达屏障前、屏障动作中或屏障之后,配合正确的内存可见性与并发访问机制。
屏障点前:确保写操作完成且可见
每个线程在调用 await() 之前,必须完成对共享资源(如结果数组、计数器、状态标志)的更新。但仅写入还不够,JVM 可能因重排序或缓存导致其他线程看不到最新值。
- 局部计算结果建议存入 volatile 数组 或 ConcurrentHashMap 等线程安全容器
- 若用普通字段(如 static int sum),需搭配 synchronized 块或 AtomicInteger 保证原子性与可见性
- 避免在 await() 后直接读取未加保护的普通变量——此时可能仍是旧值
屏障动作中:集中读取与安全聚合
构造 CyclicBarrier 时传入的 barrierAction 是唯一推荐做“汇总”“校验”“状态切换”的位置。它由最后一个到达的线程执行,天然串行、无竞争。
- 可在此处从各线程写入的 volatile 数组中读取全部结果,做合并、校验或落库
- 若 barrierAction 抛出未捕获异常,整个屏障会被破坏,后续 await() 全部抛 BrokenBarrierException
- 不要在 barrierAction 中执行耗时操作(如远程调用),否则会拖慢所有线程释放
屏障点后:统一进入下一阶段的安全边界
await() 返回后,所有线程才正式进入下一阶段。这时可以安全读取已在 barrierAction 中写入的全局状态,或启动依赖前一阶段结果的新任务。
立即学习“Java免费学习笔记(深入)”;
- 例如:屏障动作把合并后的数据写入 final List<Result>,后续阶段所有线程都可只读访问
- 若需继续修改共享资源,仍需按常规方式加锁或使用并发工具,CyclicBarrier 不提供后续保护
- 注意 await() 返回值是到达序号(0 到 parties-1),可用于让首个/末个线程承担特殊职责,但不改变资源同步逻辑
异常与中断下的资源一致性保障
一个线程在 await() 时被中断、超时或 barrierAction 异常,会导致屏障破损。此时未完成的写操作可能处于中间态。
- 务必捕获 BrokenBarrierException 和 InterruptedException,做清理或回滚
- 可在 catch 块中调用 barrier.reset() 恢复屏障,但需确认当前资源状态是否允许重试
- 建议将关键状态变更(如库存预扣)放在屏障动作内完成,失败时整体回退,避免部分提交


















