CyclicBarrier的简单理解

CyclicBarrier作为Java并发包中的一种线程同步工具,允许一组线程互相等待至到达共同的障碍点后一并执行。本文介绍了CyclicBarrier的概念、特点及其使用方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

CyclicBarrier的概念

字面翻译为回环栅栏,同CountDownLatch一样,也是concurrent包中提供的多线程之间通信的一种方式。它允许一组线程在等待某个状态后再全部同时执行。它允许一组线程互相等待对方,直到到达一个公共障碍点(barrier point)。它的一个典型应用是一组固定个数的线程需要互相等待,直到全部执行完成后,再继续执行。

之所以称为Cyclic,是因为所有等待线程被释放后,它还可以被重用(re-used),这是它区别于CountDownLatch的一个特征。

CyclicBarrier的用法

CyclicBarrier提供了两个构造方法:

public CyclicBarrier(int parties) {
    this(parties, null);
}

public CyclicBarrier(int parties, Runnable barrierAction) {
    if (parties <= 0) throw new IllegalArgumentException();
    this.parties = parties;
    this.count = parties;
    this.barrierCommand = barrierAction;
}

其中一个构造方法接收一个Runnable任务,当个数为parties的线程全部调用了await()方法后,CyclicBarrier会选择其中一个线程来执行barrierAction任务(详见 http://www.importnew.com/21889.html)。

<think>我们正在讨论Java中的CyclicBarrier,这是一个同步辅助工具,允许一组线程互相等待,直到所有线程都到达某个屏障点。根据用户的需求,我们需要提供CyclicBarrier的使用示例代码。参考引用中提供了几个示例,我们可以整合这些示例,给出一个清晰的使用示例。CyclicBarrier的基本使用步骤:1.创建一个CyclicBarrier对象,指定需要等待的线程数(parties)以及一个可选的屏障动作(Runnable),当所有线程到达屏障时会执行这个动作。2.每个线程在完成自己的任务后,调用`await()`方法,表示自己已经到达屏障,然后当前线程会被阻塞,直到所有线程都到达屏障。3.当所有线程都到达屏障后,屏障会打开,所有线程继续执行,并且先执行屏障动作(如果设置了的话),然后所有线程继续执行后续任务。我们参考引用[3]中的代码示例,因为它是一个简单的控制台程序,易于理解。同时,引用[4]中有一个图形界面的例子,但为了简洁,我们使用控制台示例。下面是一个使用CyclicBarrier的示例代码,模拟多个线程执行任务,并在所有线程到达屏障后执行一个汇总操作。注意:需要处理中断异常和BrokenBarrierException。示例代码:```javaimportjava.util.concurrent.BrokenBarrierException;importjava.util.concurrent.CyclicBarrier;publicclassCyclicBarrierExample{publicstaticvoidmain(String[]args){//定义需要等待的线程数finalintnumberOfThreads=3;//创建一个CyclicBarrier,当所有线程到达屏障时,执行一个Runnable任务(屏障动作)CyclicBarrierbarrier=newCyclicBarrier(numberOfThreads,()->{System.out.println("所有线程已到达屏障,开始执行屏障动作...");//这里可以执行一些汇总操作等});//创建并启动多个线程for(inti=0;i<numberOfThreads;i++){newThread(newWorker(barrier,i),"线程"+i).start();}}staticclassWorkerimplementsRunnable{privatefinalCyclicBarrierbarrier;privatefinalintid;publicWorker(CyclicBarrierbarrier,intid){this.barrier=barrier;this.id=id;}@Overridepublicvoidrun(){try{System.out.println(Thread.currentThread().getName()+"正在执行任务...");//模拟任务执行时间Thread.sleep((long)(Math.random()*2000));System.out.println(Thread.currentThread().getName()+"完成任务,等待其他线程...");//等待其他线程,当所有线程都到达屏障后,屏障才会打开barrier.await();//屏障打开后,所有线程继续执行后续任务System.out.println(Thread.currentThread().getName()+"继续执行后续任务...");}catch(InterruptedException|BrokenBarrierExceptione){Thread.currentThread().interrupt();e.printStackTrace();}}}}```代码说明:-我们创建了一个`CyclicBarrier`对象,指定了需要等待的线程数量(3个)和一个屏障动作(在所有线程到达后执行)。-每个Worker线程在执行完自己的任务后,调用`await()`方法等待其他线程。-当所有3个线程都调用了`await()`后,屏障动作会先执行(打印一条消息),然后所有线程继续执行后续代码。注意:`await()`方法可能会抛出`InterruptedException`(当前线程在等待时被中断)和`BrokenBarrierException`(屏障被破坏,例如某个等待的线程被中断或超时,导致屏障失效)。CyclicBarrier可以重复使用,当所有线程通过屏障后,屏障会自动重置,可以再次使用。相关问题:1.CyclicBarrier和CountDownLatch有什么区别?2.CyclicBarrier的屏障动作是在哪个线程中执行的?3.如何处理CyclicBarrier中的异常?</think>### CyclicBarrier 使用示例代码 `CyclicBarrier` 是 Java 并发包中的同步工具,它允许一组线程互相等待,直到所有线程都到达某个屏障点(barrier point)后再继续执行。以下是一个完整的使用示例: ```java import java.util.concurrent.*; public class CyclicBarrierExample { public static void main(String[] args) { // 1. 创建屏障(指定3个线程和屏障触发时的回调) CyclicBarrier barrier = new CyclicBarrier(3, () -> System.out.println("\n所有线程已就绪!开始执行核心任务...") ); // 2. 创建线程池 ExecutorService executor = Executors.newFixedThreadPool(3); // 3. 提交任务 for (int i = 1; i <= 3; i++) { executor.submit(new Worker(barrier, "Worker-" + i)); } executor.shutdown(); } static class Worker implements Runnable { private final CyclicBarrier barrier; private final String name; public Worker(CyclicBarrier barrier, String name) { this.barrier = barrier; this.name = name; } @Override public void run() { try { // 第一阶段:准备工作 System.out.println(name + " 正在准备数据..."); Thread.sleep((long)(Math.random() * 2000)); // 模拟准备耗时 // 等待所有线程完成准备 System.out.println(name + " 准备完成,等待其他线程"); barrier.await(); // 在此阻塞直到所有线程到达 // 第二阶段:核心任务(屏障打开后执行) System.out.println(name + " 开始执行核心任务"); Thread.sleep(1000); // 模拟任务执行 System.out.println(name + " 任务完成!"); } catch (InterruptedException | BrokenBarrierException e) { e.printStackTrace(); } } } } ``` #### 代码说明: 1. **屏障创建** `new CyclicBarrier(3, barrierAction)` 表示: - 需要等待 **3 个线程**到达屏障点 - 当所有线程到达时,自动执行屏障操作(打印提示) 2. **工作流程**: - 每个 `Worker` 先执行准备阶段(随机耗时) - 调用 `barrier.await()` 进入等待状态 - 当**所有 3 个线程**都调用 `await()` 后: - 屏障操作被执行(打印提示) - 所有线程**同时继续执行**后续任务 3. **输出示例**: ``` Worker-1 正在准备数据... Worker-2 正在准备数据... Worker-3 正在准备数据... Worker-1 准备完成,等待其他线程 Worker-3 准备完成,等待其他线程 Worker-2 准备完成,等待其他线程 所有线程已就绪!开始执行核心任务... Worker-2 开始执行核心任务 Worker-1 开始执行核心任务 Worker-3 开始执行核心任务 Worker-3 任务完成! Worker-1 任务完成! Worker-2 任务完成! ``` #### 关键特性: 1. **可重用性** 屏障被触发后会自动重置,可重复使用(区别于 `CountDownLatch`) 2. **屏障操作** 通过构造函数传入 `Runnable`,会在**最后一个到达的线程**中执行[^3] 3. **异常处理**: - `BrokenBarrierException`:当某个等待线程被中断或超时 - `InterruptedException`:线程在等待时被中断 4. **超时控制**: 可使用 `await(long timeout, TimeUnit unit)` 防止无限等待 #### 典型应用场景: - 多线程数据准备后的聚合计算 - 并行任务的分阶段执行控制 - 分布式测试中模拟并发请求[^2]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值