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

相关推荐
何以解忧,唯有..20 分钟前
LangChain 工具调用(Tool Calling)实战指南
java·前端·langchain
QQ_21696290961 小时前
【源码编号:project79475】SpringBoot校内二手交易平台:商品发布、分类检索、留言交流、订单管理全流程实战
java·spring boot·后端
前端 贾公子2 小时前
第09章:上下文与记忆 (2)
java·服务器·前端
2601_962203512 小时前
Java进阶07集合(续)
java·开发语言
郑州光合科技余经理2 小时前
本地生活服务系统:模块边界与结算字段怎么拆
java·开发语言·前端·后端·系统架构·uni-app·php
roman_日积跬步-终至千里3 小时前
【数据治理(6)】DataOps 不是调度工具,而是让数据产品长期可信的运行机制
java·服务器·网络
落魄大学生之流水线上谋生计3 小时前
LangGraph 基本用法指南
java·windows·python·langchain
2601_962128413 小时前
SpringBoot篇(缓存层)
java·spring boot·缓存
Dovis(誓平步青云)3 小时前
折叠屏悬停看视频,上半屏和下半屏应该各做什么
android·java·服务器·开发语言·安全·音视频
2501_937860944 小时前
Java多线程初阶(下)—— synchronized、volatile、wait/notify与经典并发工具
java·开发语言·jvm