java常用的并发工具类-CyclicBarrier

2024-09-04 11:20

本文主要是介绍java常用的并发工具类-CyclicBarrier,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、CyclicBarrier 的概述

CyclicBarrier 是 Java 并发包(java.util.concurrent)中的一个同步辅助类。它允许一组线程互相等待,直到所有线程都到达一个公共的屏障点(barrier)。当最后一个线程到达时,屏障就会打开,所有线程可以继续执行。CyclicBarrier 可以被反复使用,即当线程们通过屏障后,它可以被重置并再次使用。

1.1 主要构造方法

CyclicBarrier 提供了两个主要的构造方法:

  1. CyclicBarrier(int parties):创建一个新的 CyclicBarrier,指定参与者的数量(即线程数)。
  2. CyclicBarrier(int parties, Runnable barrierAction):除了指定线程数外,还可以提供一个在最后一个线程到达屏障时执行的动作(barrierAction)。
1.2 工作原理

CyclicBarrier 的工作原理非常简单。假设有 N 个线程,它们必须在某个时刻同步。你可以创建一个 CyclicBarrier,并将 N 传递给它。每个线程调用 await() 方法时,都会进入阻塞状态,直到第 N 个线程也调用了 await() 方法,此时所有线程都被释放,继续执行各自的后续操作。

二、CyclicBarrier 的使用方法

下面是 CyclicBarrier 的基本用法示例。

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;public class CyclicBarrierExample {public static void main(String[] args) {int numberOfThreads = 5;CyclicBarrier barrier = new CyclicBarrier(numberOfThreads, () -> {System.out.println("All parties have arrived at the barrier, let's proceed.");});for (int i = 0; i < numberOfThreads; i++) {new Thread(new Task(barrier)).start();}}
}class Task implements Runnable {private CyclicBarrier barrier;public Task(CyclicBarrier barrier) {this.barrier = barrier;}@Overridepublic void run() {System.out.println(Thread.currentThread().getName() + " is waiting at the barrier.");try {barrier.await();System.out.println(Thread.currentThread().getName() + " has crossed the barrier.");} catch (InterruptedException | BrokenBarrierException e) {e.printStackTrace();}}
}

在这个例子中,有 5 个线程需要在同一个屏障点等待。CyclicBarrier 的构造函数中传递了一个 Runnable 实例,这个实例将在所有线程到达屏障后被执行。所有线程在到达屏障后,会被阻塞,直到所有线程都调用了 await() 方法。然后,所有线程都会继续执行。

三、CyclicBarrier 的应用场景

CyclicBarrier 适用于那些需要线程协同工作的场景,例如:

3.1 多阶段任务

在多阶段任务中,每个阶段都需要多个线程同时完成。使用 CyclicBarrier,可以确保所有线程在进入下一个阶段之前都已完成当前阶段的工作。

3.2 集群计算

在分布式计算或并行处理场景下,多个线程(或节点)需要处理数据的不同部分,然后在某个时刻合并结果。这种情况下,CyclicBarrier 可以用来同步所有线程,使它们在合并数据之前完成各自的计算任务。

3.3 测试并发代码

在测试并发代码时,需要多个线程同时启动执行,以模拟高并发场景。CyclicBarrier 可以帮助实现这一点,通过让所有线程在相同点启动,从而模拟并发。

四、CyclicBarrier 与其他并发工具类的对比

4.1 CyclicBarrier vs CountDownLatch

CountDownLatch 也是一个常用的同步工具类,但与 CyclicBarrier 不同。CountDownLatch 允许一个或多个线程等待一组其他线程完成,而 CyclicBarrier 是让一组线程相互等待,直到所有线程都到达某个共同点。CountDownLatch 是一次性的,而 CyclicBarrier 是循环使用的。

4.2 CyclicBarrier vs Phaser

Phaser 是一个更复杂且灵活的同步工具类,它可以用来替代 CyclicBarrier 和 CountDownLatch。Phaser 支持动态增加或减少参与者,并且适用于更加复杂的阶段任务。CyclicBarrier 适用于简单的场景,而 Phaser 则适合处理更复杂的多阶段同步。

五、CyclicBarrier 的常见问题

  1. 线程抛出异常导致屏障失效:如果某个线程在调用 await() 方法后抛出异常,那么屏障可能会处于“破损”状态,此时所有后续调用 await() 的线程会抛出 BrokenBarrierException
  2. 屏障的重用性:每当所有线程通过屏障后,CyclicBarrier 会自动重置,并可以再次使用。这与 CountDownLatch 的一次性使用有很大的不同。
  3. 超时机制:CyclicBarrier 的 await() 方法还支持超时机制,可以指定一个最大等待时间,如果在超时时间内屏障没有被触发,线程将抛出 TimeoutException

六、总结

CyclicBarrier 是 Java 并发编程中的重要工具类,用于在多线程环境中实现线程之间的同步。它允许一组线程在一个共同点等待,直到所有线程都到达后再继续执行。CyclicBarrier 非常适合多阶段任务、集群计算和测试并发代码等场景。尽管 CyclicBarrier 在许多场景中非常有用,但在复杂的并发控制需求下,Phaser 可能会是一个更好的选择。
CyclicBarrier 是 Java 并发编程中一个非常有用的工具类,用于协调多个线程之间的同步。在并发编程中,有时需要让多个线程在执行到某个点时彼此等待,直到所有线程都到达这个点后再继续执行。这种场景下,CyclicBarrier 是一个很好的选择。

这篇关于java常用的并发工具类-CyclicBarrier的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1135875

相关文章

Java中的Cursor使用详解

《Java中的Cursor使用详解》本文介绍了Java中的Cursor接口及其在大数据集处理中的优势,包括逐行读取、分页处理、流控制、动态改变查询、并发控制和减少网络流量等,感兴趣的朋友一起看看吧... 最近看代码,有一段代码涉及到Cursor,感觉写法挺有意思的。注意是Cursor,而不是Consumer

解决java.lang.NullPointerException问题(空指针异常)

《解决java.lang.NullPointerException问题(空指针异常)》本文详细介绍了Java中的NullPointerException异常及其常见原因,包括对象引用为null、数组元... 目录Java.lang.NullPointerException(空指针异常)NullPointer

javaScript在表单提交时获取表单数据的示例代码

《javaScript在表单提交时获取表单数据的示例代码》本文介绍了五种在JavaScript中获取表单数据的方法:使用FormData对象、手动提取表单数据、使用querySelector获取单个字... 方法 1:使用 FormData 对象FormData 是一个方便的内置对象,用于获取表单中的键值

前端知识点之Javascript选择输入框confirm用法

《前端知识点之Javascript选择输入框confirm用法》:本文主要介绍JavaScript中的confirm方法的基本用法、功能特点、注意事项及常见用途,文中通过代码介绍的非常详细,对大家... 目录1. 基本用法2. 功能特点①阻塞行为:confirm 对话框会阻塞脚本的执行,直到用户作出选择。②

Docker部署Jenkins持续集成(CI)工具的实现

《Docker部署Jenkins持续集成(CI)工具的实现》Jenkins是一个流行的开源自动化工具,广泛应用于持续集成(CI)和持续交付(CD)的环境中,本文介绍了使用Docker部署Jenkins... 目录前言一、准备工作二、设置变量和目录结构三、配置 docker 权限和网络四、启动 Jenkins

SpringBoot项目注入 traceId 追踪整个请求的日志链路(过程详解)

《SpringBoot项目注入traceId追踪整个请求的日志链路(过程详解)》本文介绍了如何在单体SpringBoot项目中通过手动实现过滤器或拦截器来注入traceId,以追踪整个请求的日志链... SpringBoot项目注入 traceId 来追踪整个请求的日志链路,有了 traceId, 我们在排

Java实战之利用POI生成Excel图表

《Java实战之利用POI生成Excel图表》ApachePOI是Java生态中处理Office文档的核心工具,这篇文章主要为大家详细介绍了如何在Excel中创建折线图,柱状图,饼图等常见图表,需要的... 目录一、环境配置与依赖管理二、数据源准备与工作表构建三、图表生成核心步骤1. 折线图(Line Ch

Python中常用的四种取整方式分享

《Python中常用的四种取整方式分享》在数据处理和数值计算中,取整操作是非常常见的需求,Python提供了多种取整方式,本文为大家整理了四种常用的方法,希望对大家有所帮助... 目录引言向零取整(Truncate)向下取整(Floor)向上取整(Ceil)四舍五入(Round)四种取整方式的对比综合示例应

Spring Boot 3 整合 Spring Cloud Gateway实践过程

《SpringBoot3整合SpringCloudGateway实践过程》本文介绍了如何使用SpringCloudAlibaba2023.0.0.0版本构建一个微服务网关,包括统一路由、限... 目录引子为什么需要微服务网关实践1.统一路由2.限流防刷3.登录鉴权小结引子当前微服务架构已成为中大型系统的标

Java集合中的List超详细讲解

《Java集合中的List超详细讲解》本文详细介绍了Java集合框架中的List接口,包括其在集合中的位置、继承体系、常用操作和代码示例,以及不同实现类(如ArrayList、LinkedList和V... 目录一,List的继承体系二,List的常用操作及代码示例1,创建List实例2,增加元素3,访问元