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 不同,它强调线程间的对等协作而非单向依赖。

相关推荐
叫我阿柒啊2 小时前
Java全栈开发面试实战:从基础到微服务架构
java·vue.js·spring boot·redis·git·full stack·interview
小凡敲代码2 小时前
2025年金九银十Java面试场景题大全:高频考点+深度解析+实战方案
java·程序员·java面试·后端开发·求职面试·java场景题·金九银十
拉法豆粉3 小时前
在压力测试中如何确定合适的并发用户数?
java·开发语言
爱上纯净的蓝天3 小时前
迁移面试题
java·网络·c++·pdf·c#
chenglin0164 小时前
Logstash_Input插件
java·开发语言
bemyrunningdog5 小时前
Spring文件上传核心技术解析
java
Fireworkitte5 小时前
Java 系统中实现高性能
java
ningqw5 小时前
JWT 的使用
java·后端·springboot
David爱编程6 小时前
指令重排与内存屏障:并发语义的隐形守护者
java·后端
ZZHow10246 小时前
Java项目-苍穹外卖_Day1
java·spring boot·web