循环栅栏CyclicBarrier举例分析

发布时间:2021-12-14 15:15:05 作者:iii
来源:亿速云 阅读:130
# 循环栅栏CyclicBarrier举例分析

## 一、CyclicBarrier概述

CyclicBarrier是Java并发包(java.util.concurrent)中的一个同步辅助类,允许一组线程相互等待,直到到达某个公共屏障点(common barrier point)。与CountDownLatch不同,CyclicBarrier具有以下特点:
- **可重用性**:屏障被触发后可重置使用
- **回调机制**:支持设置屏障触发时的回调任务
- **线程阻塞**:调用await()的线程会被阻塞直到达到指定数量

## 二、核心方法解析

```java
// 构造函数(指定参与线程数和屏障触发时的回调)
CyclicBarrier(int parties, Runnable barrierAction)

// 线程调用此方法后会被阻塞,直到足够数量的线程到达
int await() throws InterruptedException, BrokenBarrierException

// 带超时的await版本
int await(long timeout, TimeUnit unit) 
    throws InterruptedException, BrokenBarrierException, TimeoutException

三、实际应用案例

场景描述:多阶段数据处理

假设我们需要处理一个大型数据集,分为三个阶段: 1. 数据加载阶段 2. 数据清洗阶段 3. 数据分析阶段

要求所有线程完成当前阶段后才能进入下一阶段。

代码实现

public class DataProcessingTask implements Runnable {
    private static final int THREAD_COUNT = 3;
    private static CyclicBarrier barrier = new CyclicBarrier(THREAD_COUNT, () -> {
        System.out.println("所有线程已完成当前阶段,准备进入下一阶段");
    });

    private final int threadId;
    
    public DataProcessingTask(int id) {
        this.threadId = id;
    }
    
    @Override
    public void run() {
        try {
            // 阶段1:数据加载
            System.out.println("线程"+threadId+"加载数据完成");
            barrier.await();
            
            // 阶段2:数据清洗
            System.out.println("线程"+threadId+"清洗数据完成");
            barrier.await();
            
            // 阶段3:数据分析
            System.out.println("线程"+threadId+"分析数据完成");
            barrier.await();
            
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        for (int i = 0; i < THREAD_COUNT; i++) {
            new Thread(new DataProcessingTask(i)).start();
        }
    }
}

执行结果示例

线程0加载数据完成
线程1加载数据完成
线程2加载数据完成
所有线程已完成当前阶段,准备进入下一阶段
线程2清洗数据完成
线程0清洗数据完成
线程1清洗数据完成
所有线程已完成当前阶段,准备进入下一阶段
线程1分析数据完成
线程0分析数据完成
线程2分析数据完成
所有线程已完成当前阶段,准备进入下一阶段

四、关键特性分析

  1. 循环使用机制

    • 每次所有线程到达屏障后,计数器会自动重置
    • 相比CountDownLatch无需重新创建新实例
  2. 异常处理

    • 当线程在await时被中断,会抛出InterruptedException
    • 如果某个线程发生超时,其他等待线程会抛出BrokenBarrierException
  3. 屏障动作执行

    • 最后一个到达屏障的线程会执行barrierAction
    • 该动作执行完毕后才会释放所有等待线程

五、适用场景对比

场景 CyclicBarrier CountDownLatch
多阶段任务同步
一次性屏障
可重置计数器
主线程等待子线程完成

六、注意事项

  1. 确保正确设置parties数量(应与实际线程数一致)
  2. 考虑使用带超时的await方法防止死锁
  3. 当线程被中断时,需要通过isBroken()检查屏障状态
  4. 回调任务barrierAction应避免长时间操作

CyclicBarrier特别适用于需要多轮同步的并行计算场景,如MapReduce中的分阶段处理、多线程测试等场景。合理使用可以显著提高多线程协作的效率。 “`

推荐阅读:
  1. mysql举例分析
  2. Java如何实现闭锁与栅栏

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

cyclicbarrier

上一篇:Tomcat中间件基线核查的示例分析

下一篇:云桌面有哪些地方是传统PC所无法比拟的

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》