barrieraction 由最后一个到达的线程同步执行,紧接计数归零后、释放其他线程前;运行于该线程上下文,每轮仅执行一次,须轻量且避免阻塞或异常。

BarrierAction 在所有线程都成功调用 await() 后,由**最后一个到达的线程同步执行**——不是另起线程,也不是提前或延后,而是紧接在计数归零之后、释放其他线程之前那一刻。
触发时机:严格依赖“最后一位抵达者”
当第 parties 个线程调用 await() 时:
- 内部计数器
count减至 0,判定为“全员到齐” - 该线程立即获得执行
barrierCommand.run()的权限 - 它必须完整执行完 barrierAction,才能调用
signalAll()唤醒其余线程 - 若 barrierAction 抛出未捕获异常(如
RuntimeException),会被包装为BrokenBarrierException,并传播给所有等待中的线程(包括它自己)
执行环境:共享抵达线程的上下文
barrierAction 没有独立线程或调度器,它直接运行在那个“凑齐人数”的线程栈中:
- 继承该线程的
ClassLoader、ThreadLocal和安全上下文 - 不会自动加入任何线程池;如需异步处理(例如发通知、写日志),必须显式提交任务(如
executor.submit(...)) - 若执行耗时过长,所有等待线程将持续阻塞,可能引发超时或级联失败
作用范围:仅限本轮、仅执行一次
barrierAction 是每轮屏障动作的“临界段”,不是通用回调:
- 只在当前
Generation(即本轮)中执行一次;下一轮自动重置,重新计数 - 只有所有线程都正常到达(无中断、无超时、无异常退出),它才会执行
- 若任一线程被中断或 await 超时,屏障进入 broken 状态,barrierAction 被跳过
- 不能在 barrierAction 内再次调用
await(),否则会导致死锁
实用建议:轻量、安全、可预测
设计 barrierAction 时应视其为同步关卡的一部分:
- 适合做结果聚合(读取线程安全容器里的数据)、状态标记、轻量日志输出
- 避免 I/O、远程调用、加锁、数据库操作等不确定耗时行为
- 如需传递上下文(如 MDC 日志标记),应在各工作线程调用
await()前主动设置,并在 barrierAction 中显式读取 - 异常时 barrierAction 不会执行,因此关键清理逻辑不应只依赖它(比如资源释放应放在 try-finally 中)
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











