深入理解 Java CyclicBarrier

news/2025/1/30 13:16:57/文章来源:https://www.cnblogs.com/happy-coding/p/18694483

简介

在 Java 的并发编程中,CyclicBarrier 是一个非常有用的同步辅助类。它允许一组线程相互等待,直到所有线程都到达某个共同的屏障点。与 CountDownLatch 相比,CyclicBarrier 可以被重用,是一个更灵活的同步工具。本文将详细解释 CyclicBarrier 的基本概念、使用方法以及最佳实践。

目录

  1. 基础概念
  2. 使用方法
  3. 常见实践
  4. 最佳实践
  5. 小结
  6. 参考资料

基础概念

CyclicBarrier 是 java.util.concurrent 包中提供的一个并发工具类,最常用于需要所有线程在继续执行前都达到某个点的场景。CyclicBarrier 可以看作是一组线程互相等待的一个屏障,一旦所有线程都达到这一屏障,则所有线程可以继续执行。

关键特性

  • 线程集结:一个 CyclicBarrier 被初始化时,需要一个线程数量,只有当固定数量的线程调用了 await() 方法之后,这些线程才能继续执行。
  • 重用性:CyclicBarrier 允许在同一个对象上多次调用 await(),即可以被重用。
  • 可选的 Barrier Action:在所有线程到达屏障后,可以指定一个可选的 Runnable 作为屏障动作。

使用方法

CyclicBarrier 的基本用法

要使用 CyclicBarrier,我们首先需要创建一个 CyclicBarrier 的实例,并指定参与的线程数。每个线程在到达屏障时调用 await() 方法。一旦所有线程都调用了 await() 方法,所有线程将被释放继续执行。

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;public class CyclicBarrierExample {public static void main(String[] args) {final int threadCount = 3;CyclicBarrier barrier = new CyclicBarrier(threadCount, () -> {System.out.println("所有线程已到达屏障,继续执行...");});for (int i = 0; i < threadCount; i++) {new Thread(new Task(barrier), "线程-" + i).start();}}static class Task implements Runnable {private CyclicBarrier barrier;public Task(CyclicBarrier barrier) {this.barrier = barrier;}@Overridepublic void run() {try {System.out.println(Thread.currentThread().getName() + " 正在等待...");barrier.await();System.out.println(Thread.currentThread().getName() + " 继续执行...");} catch (InterruptedException | BrokenBarrierException e) {e.printStackTrace();}}}
}

CyclicBarrier 带有障碍动作(Barrier Action)

Barrier Action 是一个可选操作,由主线程在所有参与线程到达屏障后执行。可以在构造函数中传递一个 Runnable 来设置该动作。

CyclicBarrier barrier = new CyclicBarrier(3, () -> {System.out.println("所有线程到达屏障点 - 执行 Barrier Action!");
});

常见实践

  1. 多线程计算结果合并:将大任务分解为若干个子任务,使用 CyclicBarrier 等待所有子任务完成,再合并结果。
  2. 模拟并发场景:测试在并发环境中某段代码在所有线程同时开始执行后的行为。
  3. 分段处理:按分段处理任务,每一段任务完成后进行下一个步骤。

最佳实践

  1. 处理中断:在使用 await() 方法时,需要正确处理InterruptedException 和 BrokenBarrierException。
  2. 重用性考虑:如果同一批任务需要循环执行,可以利用 CyclicBarrier 的复用特性。
  3. 线程数匹配:确保参与的线程数量和 CyclicBarrier 的初始数量匹配,否则会导致线程永远等待。

小结

CyclicBarrier 是一个强大且灵活的工具,适合用在多线程需要同步到共同点再继续执行的情况。通过适当的例子和最佳实践应用,我们可以有效地协调多线程环境中的任务执行。

参考资料

  • Java官方文档
  • Java并发编程实战
  • Java多线程编程核心技术

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/876722.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

又在折磨自己

不是吕波是滤波过年好,但我最近真的好想死,听说卡尔曼吕波很重要,为了让自己死得快一点来学学卡尔曼吕波,我对我接下来的半个月充满了绝望。 新年第一天就这么丧可不好,振作起来,人活着总要学会开开心心的,然后少管一些不开心的事情,其实别人也并没有很重要对不对,希望…

Quid faciam?

「先生、人生相談です。 この先どうなら楽ですか。 そんなの誰もわかりはしないよなんて言われますか。 ほら、苦しさなんて欲しいわけない。 何もしないで生きていたい。 青空だけが見たいのは我儘ですか。 」每到这种时候都感觉要撑不住了。 此时此刻眼眶就不禁为黏糊糊的透明…

【牛客训练记录】牛客2025年除夕娱乐赛

训练情况赛后反思 据说是临时准备的,今年好像没啥乐子题,除了两道猜猜题 A题 构造一个字符串使得 jiaran 子串至少出现 114514 次,直接输出 114514 次 jiaran点击查看代码 #include <bits/stdc++.h> // #define int long long #define endl \nusing namespace std;voi…

互联网不景气了那就玩玩嵌入式吧,用纯.NET开发并制作一个智能桌面机器人(三):用.NET IoT库控制舵机并多方法播放表情

前言 前面两篇文章讲了.NET IoT相关的知识点,以及硬件的GPIO的一些概念,还有点亮两个屏幕的方法,这些让大家对.NET的用途有了新的认识,那我们这回继续讲解.NET IoT的知识点,以及介绍一些好玩的东西,例如让视频通过机器人的屏幕播放起来,还有机器人的身体也能通过我们的代…

数据库物理备份:保障数据完整性和业务连续性的关键策略

title: 数据库物理备份:保障数据完整性和业务连续性的关键策略 date: 2025/1/29 updated: 2025/1/29 author: cmdragon excerpt: 在现代企业中,数据被视为最重要的资产之一。因此,确保数据的安全性、完整性和可用性是每个数据库管理员(DBA)的首要任务。在数据管理的过程…

《Operating System Concepts》阅读笔记:p1-p1

《Operating System Concepts》学习第 1 天,p1-p1 总结,总计 1 页。 一、技术总结 无。 二、英语总结(生词:1) 1.intermediary (1)intermediary: inter-("between, among") + medius("middle") c.intermediary originally referred to something or so…

【持续更新中】线段树全集

引入 一个数列,单点修改(加),区间查询(和)。 上述问题有很多种解法,如树状数组、分块、平衡树等,今天的主题是著名的线段树。 正题 (不确保按难度升序排序,自己看着目录调顺序吧) 线段树基本原理 因为需要区间查询,所以我们希望有一些捷径能将部分的数的和提前算好…

读量子霸权18读后总结与感想兼导读

《量子霸权》读书笔记,读薄率约23.48%,涵盖量子宇宙、量子计算机等读厚方向。笔记详细记录了各章节内容,亮点包括量子计算介绍、与传统计算机比较、与AI关系及平行宇宙探讨。1. 基本信息 量子霸权【美】加来道雄 著中信出版集团股份有限公司,2024年4月出版1.1. 读薄率 书籍总…

C# WinForm 自定义类型转换器重新编译后修改属性提示 InstanceDescriptor 错误的解决方案

当我们编写自定义的类型转换器比如从 TypeConverter、ExpandableObjectConverter 等继承,首次编译后,修改属性值是正常的,当再次编译后,再次修改属性则会提示如下错误: 属性“属性名”的代码生成失败。错误是: “类型转换器类名”无法将“属性名”转换为“System.Componen…

简单的javaweb

在这里我们可以看到springboots的基本结构 controller(控制器) 负责处理HTTP请求,调用相应的服务层方法,并返回视图或数据。 DailyReportController、InternalMessageController、PersonInfoController:这些是具体的控制器类,分别处理与日报、内部消息和个人信息相关的请…

AMD核显运行DeepseekR1-7b:使用mlc-llm框架,利用vulkan推理

任何支持vulkan的显卡都能跑! 本文使用的是Radeon890M核显,内存有多大就等于显存有多大。劲啊 1. 安装mlc-llm 官方文档 windows+vulkan: conda activate your-environment pip install --pre -U -f https://mlc.ai/wheels mlc-llm-nightly-cpu mlc-ai-nightly-cpulinux+vulk…