CyclicBarrier 使用详解

简介: 本文主要对CyclicBarrier的相关知识点进行了介绍和讲解

1、什么是CyclicBarrier

CyclicBarrier是一个同步屏障,它允许多个线程相互等待,直到到达某个公共屏障点,才能继续执行。也就是说它的作用就是会让所有线程都等待完成后才会继续下一步行动。

举个简单的例子就是在学校参加会议时,有的同学早到,有的晚到,但是必须等待所有同学都到齐才能开始会议,这里的同学指的就是各个线程,会议就是CyclicBarrier.

2、如何使用CyclicBarrier

2.1 构造方法

publicCyclicBarrier(intparties)
publicCyclicBarrier(intparties, RunnablebarrierAction)

解析:

  • parties 是参与线程的个数
  • 第二个构造方法有一个 Runnable 参数,这个参数的意思是最后一个到达线程要做的任务

2.2 重要方法


public int await() throws InterruptedException, BrokenBarrierException
public int await(long timeout, TimeUnit unit) throws InterruptedException, BrokenBarrierException, TimeoutException

解析:

  • 线程调用 await() 表示自己已经到达栅栏,每调用一次await()方法都将使阻塞的线程数+1,只有阻塞的线程数达到设定值时屏障才会打开,允许阻塞的所有线程继续执行。
  • BrokenBarrierException 表示栅栏已经被破坏,破坏的原因可能是其中一个线程 await() 时被中断或者超时。
  • 带参数的方法表示只有在指定数量的线程到达时,或者等待时间超过timeout才会放行

3、案例实现

3.1 代码实现

publicclassCyclicBarrierDemo {
staticclassTaskThreadextendsThread {
CyclicBarrierbarrier;
publicTaskThread(CyclicBarrierbarrier) {
this.barrier=barrier;
        }
@Overridepublicvoidrun() {
try {
Thread.sleep(1000);
System.out.println(getName() +" 进入会议 XXX");
//调用await()的时候,当前线程将会被阻塞,需要等待其他同学都到达await了才能继续barrier.await();
System.out.println(getName() +" 离开会议 XXX");
            } catch (Exceptione) {
e.printStackTrace();
            }
        }
    }
publicstaticvoidmain(String[] args) {
intthreadNum=5;
CyclicBarrierbarrier=newCyclicBarrier(threadNum, () ->System.out.println(Thread.currentThread().getName() +" 最后进入会议室"));
for(inti=0; i<threadNum; i++) {
newTaskThread(barrier).start();
        }
    }
}

3.2 打印结果

Thread-4进入会议XXXThread-2进入会议XXXThread-0进入会议XXXThread-1进入会议XXXThread-3进入会议XXXThread-3最后进入会议室Thread-3离开会议XXXThread-4离开会议XXXThread-1离开会议XXXThread-2离开会议XXXThread-0离开会议XXXProcessfinishedwithexitcode0

从打印结果可以看出,所有线程会等待全部线程到达栅栏之后才会继续执行,并且最后到达的线程会完成 Runnable 的任务。

4. 使用场景

可以用于多线程计算数据,最后合并计算结果的场景

相关文章
|
开发框架 安全 .NET
常见ASPX木马报错原因及解决方案
常见ASPX木马报错原因及解决方案
851 0
|
Oracle Java 关系型数据库
三分钟拿下dbeaver企业版
数据库管理工具Dbeaver,开源的企业版,功能丰富
2419 0
三分钟拿下dbeaver企业版
|
存储 SQL Java
Java8 stream 中利用 groupingBy 进行多字段分组求和
Java8 stream 中利用 groupingBy 进行多字段分组求和
|
机器学习/深度学习 Python
配置环境miniconda+pycharm【机器学习】
配置环境miniconda+pycharm【机器学习】
1468 0
|
5天前
|
存储 消息中间件 安全
企业级实时消息推送系统的架构设计,一文即懂!
如果你是技术负责人,该如何搭建一套能解决这些问题的企业级统一消息推送平台?今天我们就从核心挑战出发,拆解一套可落地的统一推送服务架构方案。
64 0
|
2月前
|
SQL 人工智能 Rust
Java 开发中Stream的toMap与Map 使用技巧
本文深入解析了 Java 中 `toMap()` 方法的三大问题:重复键抛出异常、`null` 值带来的风险以及并行流中的性能陷阱,并提供了多种替代方案,如使用 `groupingBy`、`toConcurrentMap` 及自定义收集器,帮助开发者更安全高效地进行数据处理。
166 0
|
Java 应用服务中间件 HSF
Java应用结构规范问题之配置Logback以在控制台输出日志的问题如何解决
Java应用结构规范问题之配置Logback以在控制台输出日志的问题如何解决
251 7
|
SQL NoSQL 数据库
Flutter Hive NoSql 数据库使用指南
本文将会写一个 Hive CURD 的例子,详细介绍 Hive 这个轻量级的 Flutter 离线数据库的使用方法,包括 Hive 在 Flutter 开发中的重要性、Hive 与 SQLite 的比较等,帮助开发者快速上手 Hive 数据库。
331 6
Flutter Hive NoSql 数据库使用指南
|
Java 应用服务中间件 微服务
spring boot 中Feign调用提示Request header is too large 解决方案
spring boot 中Feign调用提示Request header is too large 解决方案
766 1
|
机器学习/深度学习 算法 Python
探索Python中的基础算法:梯度提升机(GBM)
探索Python中的基础算法:梯度提升机(GBM)
620 2