CyclicBarrier详解

CyclicBarrier 是 Java 并发工具类,基于屏障点(Barrier)实现多线程协同等待。通过 await() 阻塞线程直至所有线程到达屏障,支持重置和屏障后动作。常用于分阶段任务或并行计算结果的合并。


一、核心功能

  1. 协同等待:多个线程互相等待,直到全部到达屏障点后继续执行。
  2. 可重用性:计数器可重置,支持多次任务分阶段执行。
  3. 屏障后动作 :所有线程到达屏障后,可触发自定义的 Runnable 任务(如合并结果)。

二、核心方法

方法 说明
CyclicBarrier(int parties) 构造方法,指定等待的线程数
CyclicBarrier(int parties, Runnable barrierAction) 指定线程数和屏障后触发的任务
int await() 阻塞当前线程,直到所有线程到达屏障
int await(long timeout, TimeUnit unit) 带超时的等待,超时抛出 TimeoutException
void reset() 重置屏障,未到达的线程将抛出 BrokenBarrierException
int getParties() 获取屏障需要的线程数
int getNumberWaiting() 获取当前等待的线程数

三、典型使用场景

  1. 多阶段任务
    例如:分批次处理数据,每批所有线程处理完成后进入下一阶段。
  2. 并行计算合并
    例如:多个线程分别计算部分结果,所有线程完成后汇总最终结果。
  3. 模拟测试
    让多个线程在特定阶段同步,观察并发行为。

四、代码示例

java 复制代码
public class CyclicBarrierDemo {
    public static void main(String[] args) {
        int threadCount = 3;
        // 定义屏障后的汇总任务
        Runnable mergeAction = () -> System.out.println("所有线程到达屏障,开始合并结果...");
        
        CyclicBarrier barrier = new CyclicBarrier(threadCount, mergeAction);

        for (int i = 0; i < threadCount; i++) {
            new Thread(() -> {
                try {
                    System.out.println("线程计算中...");
                    Thread.sleep(1000);
                    barrier.await(); // 等待其他线程
                    System.out.println("线程继续执行后续任务...");
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }).start();
        }
    }
}

五、注意事项

  1. 线程阻塞
    await() 会阻塞线程,若线程池中工作线程数不足,可能导致死锁。
  2. 异常处理
    若有线程在等待时被中断或超时,屏障将损坏(BrokenBarrierException),需调用 reset() 重置。
  3. 屏障动作执行
    屏障后的 Runnable 任务由最后到达屏障的线程执行,其他线程继续前需等待该任务完成。
  4. 重置风险
    reset() 会立即打破当前屏障,可能导致未到达的线程抛出异常,需谨慎使用。

六、对比 CountDownLatch

特性 CyclicBarrier CountDownLatch
重用性 支持重置,可重复使用 一次性
核心角色 多线程互相等待 主线程等待子线程或子线程等待主线程
触发条件 所有线程到达屏障点 计数器归零
附加任务 支持屏障后执行自定义任务

七、高级用法

1. 分阶段任务

java 复制代码
CyclicBarrier barrier = new CyclicBarrier(3, () -> System.out.println("阶段完成,进入下一阶段"));
// 多线程分阶段执行任务
for (int stage = 1; stage <= 3; stage++) {
    new Thread(() -> {
        doStageWork(stage);
        barrier.await(); // 等待所有线程完成当前阶段
    }).start();
}

2. 处理屏障损坏

java 复制代码
try {
    barrier.await();
} catch (BrokenBarrierException e) {
    System.out.println("屏障已损坏,需重置或终止任务");
    barrier.reset(); // 重置屏障
}

总结
CyclicBarrier 适用于多线程分阶段协同工作的场景,通过可重用性和屏障后任务简化复杂同步逻辑。与 CountDownLatch 不同,它强调线程间的对等协作而非单向依赖。

相关推荐
majingming1236 小时前
FUNCTION
java·前端·javascript
zopple6 小时前
常见的 Spring 项目目录结构
java·后端·spring
xuxie998 小时前
N11 ARM-irq
java·开发语言
cjy0001118 小时前
springboot的 nacos 配置获取不到导致启动失败及日志不输出问题
java·spring boot·后端
wefly20178 小时前
从使用到原理,深度解析m3u8live.cn—— 基于 HLS.js 的 M3U8 在线播放器实现
java·开发语言·前端·javascript·ecmascript·php·m3u8
zhenxin01229 小时前
Spring Boot实现定时任务
java
小江的记录本9 小时前
【事务】Spring Framework核心——事务管理:ACID特性、隔离级别、传播行为、@Transactional底层原理、失效场景
java·数据库·分布式·后端·sql·spring·面试
sheji34169 小时前
【开题答辩全过程】以 基于springboot的校园失物招领系统为例,包含答辩的问题和答案
java·spring boot·后端
寂静or沉默9 小时前
2026最新Java岗位从P5-P7的成长面试进阶资源分享!
java·开发语言·面试
卓怡学长9 小时前
m289在线交友系统
java·spring·tomcat·maven·intellij-idea·hibernate