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

相关文章

一文详解如何在idea中快速搭建一个Spring Boot项目

《一文详解如何在idea中快速搭建一个SpringBoot项目》IntelliJIDEA作为Java开发者的‌首选IDE‌,深度集成SpringBoot支持,可一键生成项目骨架、智能配置依赖,这篇文... 目录前言1、创建项目名称2、勾选需要的依赖3、在setting中检查maven4、编写数据源5、开启热

Python常用命令提示符使用方法详解

《Python常用命令提示符使用方法详解》在学习python的过程中,我们需要用到命令提示符(CMD)进行环境的配置,:本文主要介绍Python常用命令提示符使用方法的相关资料,文中通过代码介绍的... 目录一、python环境基础命令【Windows】1、检查Python是否安装2、 查看Python的安

Java对异常的认识与异常的处理小结

《Java对异常的认识与异常的处理小结》Java程序在运行时可能出现的错误或非正常情况称为异常,下面给大家介绍Java对异常的认识与异常的处理,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参... 目录一、认识异常与异常类型。二、异常的处理三、总结 一、认识异常与异常类型。(1)简单定义-什么是

SpringBoot项目配置logback-spring.xml屏蔽特定路径的日志

《SpringBoot项目配置logback-spring.xml屏蔽特定路径的日志》在SpringBoot项目中,使用logback-spring.xml配置屏蔽特定路径的日志有两种常用方式,文中的... 目录方案一:基础配置(直接关闭目标路径日志)方案二:结合 Spring Profile 按环境屏蔽关

基于Python实现一个Windows Tree命令工具

《基于Python实现一个WindowsTree命令工具》今天想要在Windows平台的CMD命令终端窗口中使用像Linux下的tree命令,打印一下目录结构层级树,然而还真有tree命令,但是发现... 目录引言实现代码使用说明可用选项示例用法功能特点添加到环境变量方法一:创建批处理文件并添加到PATH1

Java使用HttpClient实现图片下载与本地保存功能

《Java使用HttpClient实现图片下载与本地保存功能》在当今数字化时代,网络资源的获取与处理已成为软件开发中的常见需求,其中,图片作为网络上最常见的资源之一,其下载与保存功能在许多应用场景中都... 目录引言一、Apache HttpClient简介二、技术栈与环境准备三、实现图片下载与保存功能1.

python判断文件是否存在常用的几种方式

《python判断文件是否存在常用的几种方式》在Python中我们在读写文件之前,首先要做的事情就是判断文件是否存在,否则很容易发生错误的情况,:本文主要介绍python判断文件是否存在常用的几种... 目录1. 使用 os.path.exists()2. 使用 os.path.isfile()3. 使用

SpringBoot排查和解决JSON解析错误(400 Bad Request)的方法

《SpringBoot排查和解决JSON解析错误(400BadRequest)的方法》在开发SpringBootRESTfulAPI时,客户端与服务端的数据交互通常使用JSON格式,然而,JSON... 目录问题背景1. 问题描述2. 错误分析解决方案1. 手动重新输入jsON2. 使用工具清理JSON3.

java中long的一些常见用法

《java中long的一些常见用法》在Java中,long是一种基本数据类型,用于表示长整型数值,接下来通过本文给大家介绍java中long的一些常见用法,感兴趣的朋友一起看看吧... 在Java中,long是一种基本数据类型,用于表示长整型数值。它的取值范围比int更大,从-922337203685477

使用jenv工具管理多个JDK版本的方法步骤

《使用jenv工具管理多个JDK版本的方法步骤》jenv是一个开源的Java环境管理工具,旨在帮助开发者在同一台机器上轻松管理和切换多个Java版本,:本文主要介绍使用jenv工具管理多个JD... 目录一、jenv到底是干啥的?二、jenv的核心功能(一)管理多个Java版本(二)支持插件扩展(三)环境隔