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

相关推荐
毕设源码-朱学姐3 小时前
【开题答辩全过程】以 基于JavaWeb的网上家具商城设计与实现为例,包含答辩的问题和答案
java
C雨后彩虹4 小时前
CAS与其他并发方案的对比及面试常见问题
java·面试·cas·同步·异步·
java1234_小锋5 小时前
Java高频面试题:SpringBoot为什么要禁止循环依赖?
java·开发语言·面试
2501_944525545 小时前
Flutter for OpenHarmony 个人理财管理App实战 - 账户详情页面
android·java·开发语言·前端·javascript·flutter
计算机学姐5 小时前
基于SpringBoot的电影点评交流平台【协同过滤推荐算法+数据可视化统计】
java·vue.js·spring boot·spring·信息可视化·echarts·推荐算法
Filotimo_6 小时前
Tomcat的概念
java·tomcat
索荣荣6 小时前
Java Session 全面指南:原理、应用与实践(含 Spring Boot 实战)
java·spring boot·后端
Amumu121386 小时前
Vue Router(二)
java·前端
念越7 小时前
数据结构:栈堆
java·开发语言·数据结构