当前位置: 首页 > news >正文

JUC包:CyclicBarrier源码+实例讲解

1 缘起

上篇文章讲到了CountDownLatch:https://blog.csdn.net/Xin_101/article/details/129116170
作为同系的佼佼者,不得不提CyclicBarrier,
设计理念相似,都是多线程等待,但是,应用的技术以及功能不同,
下面根据源码及实例讲解,
帮助读者轻松应对知识交流与考核。

2 CyclicBarrier

同步辅助工具,允许一组线程相互等待对方达到共同的屏障点。
CyclicBarrier在固定大小的线程组中非常有用,这些线程组可以偶尔彼此等待。
这个屏障被称为循环屏障,因为释放等待线程后可以重新使用线程和屏障点。
CyclicBarrier支持Runnable(可选)命令,这个Runnable介于到达屏障点前和突破屏障点后,在每个屏障点执行一次。
Runnable屏障点操作对任何一方继续之前更新共享状态非常有用。
内存一致性影响:先调用await方法的线程动作发生在其他部分屏障操作之前(先于其他线程通过await方法获取响应结果)。

2.1 测试样例

使用CyclicBarrier有两个关键,初始化和await,
其中,初始化有两种方式,第一,使用Runnable,当到达屏障时执行;第二,不使用Runnable;
await线程等待,当同步状态为0时,唤醒线程,释放锁,突破屏障,继续执行后面的逻辑。
同时,CyclicBarrier是可重用的,先给一个测试的样例。

package com.monkey.java_study.juc;import org.apache.commons.lang3.time.StopWatch;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;import java.util.Random;
import java.util.concurrent.CyclicBarrier;/*** 测试CyclicBarrier.** @author xindaqi* @since 2023-02-20 15:48*/
public class CyclicBarrierTest {private static final Logger logger = LoggerFactory.getLogger(CyclicBarrierTest.class);static class ThreadRunner implements Runnable {private final CyclicBarrier cyclicBarrier;public ThreadRunner(CyclicBarrier cyclicBarrier) {this.cyclicBarrier = cyclicBarrier;}@Overridepublic void run() {Random random = new Random();int randomBound = 1000;try {// 第一个屏障StopWatch stopWatch = new StopWatch();stopWatch.start();Thread.sleep(random.nextInt(randomBound));stopWatch.stop();logger.info(">>>>>>>>{} 到达第一个屏障, time cost:{}", Thread.currentThread().getName(), stopWatch.formatTime());cyclicBarrier.await();logger.info(">>>>>>>>{} 突破第一个屏障, time cost:{}", Thread.currentThread().getName(), stopWatch.formatTime());// 第二个屏障stopWatch.reset();stopWatch.start();Thread.sleep(random.nextInt(randomBound));stopWatch.stop();logger.info(">>>>>>>>{} 到达第二个屏障, time cost:{}", Thread.currentThread().getName(), stopWatch.formatTime());cyclicBarrier.await();logger.info(">>>>>>>>{} 突破第二个屏障, time cost:{}", Thread.currentThread().getName(), stopWatch.formatTime());} catch (Exception ex) {throw new RuntimeException(ex);}}}public static void main(String[] args) {StopWatch stopWatch = new StopWatch();stopWatch.start();CyclicBarrier cyclicBarrier = new CyclicBarrier(3, () -> {logger.info(">>>>>>>>开始突破屏障.");});for (int i = 0; i < 3; i++) {new Thread(new ThreadRunner(cyclicBarrier)).start();}}
}

在这里插入图片描述

3 源码分析

先看下CyclicBarrier的两个属性,lock和trip,
源码如下图所示,其中,lock为ReentrantLock,trip为Condition,
由Condition可知,通过await可实现线程等待,释放锁,
CyclicBarrier通过这个技术实现线程等待,线程唤醒,实现屏障的功能。
在这里插入图片描述

3.1 初始化

先看CyclicBarrier初始化,源码如下图所示,
由图可知,参数有两个:同步状态数量和Runnable,
其中,同步状态数量表示等待线程的数量,Runnable用于到达屏障时执行逻辑。
位置:java.util.concurrent.CyclicBarrier#CyclicBarrier(int, java.lang.Runnable)
在这里插入图片描述

下面的初始化不指定Runnable,源码如下图所示,
由源码可知,只指定了同步状态数量,而Runnable则为null,后续不会执行其他逻辑。
位置:java.util.concurrent.CyclicBarrier#CyclicBarrier(int)
在这里插入图片描述

3.2 await

完成CyclicBarrier的初始化,
接下来需要维护屏障,开启线程等待,
通过await方法实现,源码如下图所示。
await有两种,带参和不带参,
不带参的源码如下图所示。
位置:java.util.concurrent.CyclicBarrier#await()
在这里插入图片描述

带参方法源码如下图所示,由图可知,
参数为超时时间,是线程等待的最大时间,线程等待超时后抛出异常。
具体的实现还要看dowait,后面接着分析。
位置:java.util.concurrent.CyclicBarrier#await(long, java.util.concurrent.TimeUnit)
在这里插入图片描述

3.2.1 dowait

dowait源码如下图所示,源码比较长,分段分析,
源码中标识了解析。
位置:java.util.concurrent.CyclicBarrier#dowait

第一段,源码如下图所示,
由源码可知,CyclicBarrier使用了可重入锁Reentrant,
一般而言,多线程使用ReentrantLock会阻塞,线程进入队列排队,
但是,正如ReentrantLock设计,对线程的使用提供了更高的灵活性,
可以通过await让线程等待,并释放锁,通过signalAll()唤醒等待的线程,
于是,CyclicBarrier多线程不会进入阻塞,而是线程进入等待状态,然后释放锁,
这样其他线程可以不用等待其他已经获得锁的线程释放锁就可以获取锁,因为其他线程进入等待状态并且释放了锁。
这部分的逻辑通过配置generation作为突破标识,
并且使同步状态减1,同步状态为0时,进入对应的逻辑,后面讲。

3.2.1.1 获取锁

在这里插入图片描述

3.2.1.2 冲破屏障

接下来进入同步状态为0的逻辑,源码如下图所示,
由图可知,
同步状态为0时,说明所有线程均已执行,并且最后一进入的线程之前的所有线程已经进入等待状态,
最后一个进入的线程执行同步状态减1后,
通过nextGeneration重置同步状态,更新generation,满足跳出自旋的条件,
并且使用signalAll唤醒所有线程,后面源码分析nextGeneration,
在finally中通过breakBarrier突破屏障,后面讲。
在这里插入图片描述
nextGeneration方法如下图所示,
由图可知,
通过newGeneration更新generation,
以满足跳出自旋的条件g != generation。
同时,通过signalAll唤醒所有线程,重置同步状态。
在这里插入图片描述

3.2.1.3 线程等待

接下来就是CyclicBarrier的等待逻辑,源码如下图所示,
由图可知,
通过自旋,实现线程相互等待,
当然,需要在完成任务后跳出自旋,通过generation作为突破屏障的标识,
当generation发生改变时,直接返回,跳出自旋,进入finally,突破屏障,
最后一个线程进入,使同步状态减为0,由前文可知,更新generation,
满足g != generation,跳出自旋,
最后,finally中的逻辑释锁。

在这里插入图片描述

4 小结

(1)CyclicBarrier通过ReentrantLock和Condition实现线程等待,释放锁,保证多线程不阻塞;
(2)以generation作为突破屏障的标志;
(3)线程间相互等待:通过自旋实现线程间相互等待,同步状态减为0时,更新generation,满足跳出自旋的条件,最后一个线程进入后,唤醒其余等待的线程,为后面重用做准备,并跳出当前自旋,突破屏障,释放锁;
(4)突破屏障:最后一个线程进入后,同步状态减为0,跳出自旋,突破屏障;
(5)CyclicBarrier线程可重用:通过重置同步状态,唤醒所有线程。

相关文章:

JUC包:CyclicBarrier源码+实例讲解

1 缘起 上篇文章讲到了CountDownLatch&#xff1a;https://blog.csdn.net/Xin_101/article/details/129116170 作为同系的佼佼者&#xff0c;不得不提CyclicBarrier&#xff0c; 设计理念相似&#xff0c;都是多线程等待&#xff0c;但是&#xff0c;应用的技术以及功能不同&a…...

Trace、Metrics、Logging 选型

背景分布式追踪的起源自从微服务的兴起开始&#xff0c;整个系统架构开始变得极为庞大和复杂&#xff0c;但是服务之间的调用关系&#xff0c;调用消耗时间等等信息却依然是半黑盒的状态。为了能够将调用的链路进行串联&#xff0c;将系统的各种指标数据展示出来以使得系统的链…...

Java验证码

文章目录一、验证码概述二、Java原生验证码1、随机数字验证码2、随机数字和字母验证码3、运算验证码三、引入三方验证码一、验证码概述 验证码&#xff08;CAPTCHA&#xff09;是“Completely Automated Public Turing test to tell Computers and Humans Apart”&#xff08;全…...

5天带你读完《Effective Java》(四)

《Effective Java》是Java开发领域无可争议的经典之作&#xff0c;连Java之父James Gosling都说&#xff1a; “如果说我需要一本Java编程的书&#xff0c;那就是它了”。它为Java程序员提供了90个富有价值的编程准则&#xff0c;适合对Java开发有一定经验想要继续深入的程序员…...

探索密码学的未来:SM1、SM2、SM3、SM4、同态加密、密态计算、隐私计算和安全多方计算

密码算法在现代通信与信息安全中发挥着至关重要的作用&#xff0c;SM1、SM2、SM3、SM4、同态加密、密态计算、隐私计算和安全多方计算等密码算法被广泛应用于各种信息安全领域。本篇博客将会为大家介绍这些密码算法&#xff0c;以及它们在信息安全中的作用和应用。 一、SM1、SM…...

【教程】去水印开源工具Lama Cleaner在Windows的安装和使用

一、Lama Cleaner是什么&#xff1f; Lama Cleaner是一款开源且免费的人工学习图片去水印程序&#xff08;个人主要学习用途&#xff09;&#xff0c;没有图片分辨率限制&#xff08;个人使用暂未发现&#xff09;&#xff0c;并且保存的图片质量很高&#xff08;个人觉得跟原…...

驾考笔记_2023

科目一1> 扣分制度1.1> 超速1.2> 超载1.3> 车牌1.4> 速记口诀2> 满分学习2.1> 消分学习2.2> 满分重考&#xff1b;3> 罚款 / 判刑3.1> 考证3.2> 审验教育3.3> 酒驾3.4> 200&#xffe5;3.5> 500&#xffe5;3.6> 2000&#xffe5…...

【架构师】跟我一起学架构——调用链

博客昵称&#xff1a;架构师Cool 最喜欢的座右铭&#xff1a;一以贯之的努力&#xff0c;不得懈怠的人生。 作者简介&#xff1a;一名Coder&#xff0c;软件设计师/鸿蒙高级工程师认证&#xff0c;在备战高级架构师/系统分析师&#xff0c;欢迎关注小弟&#xff01; 博主小留言…...

[神经网络]Swin Transformer网络

一、概述 Swin Transformer是一个用了移动窗口的层级式Vision Transformer。 在图像领域&#xff0c;Transformer需要解决如下两个问题&#xff1a; ①尺度问题&#xff1a;同一语义的物体在图像中有不一样的尺度。(大小不同) ②Resolution过大&#xff1a;若以像素点作为单位&…...

【分布式】什么是分布式,分布式和集群的区别又是什么?答案在正文。

文章目录1. 什么是分布式 ?2. 分布式与集群的区别 ?3.用一个请求串起来4.一个简化的架构图5.分布式环境的特点6.分布式环境下面临的问题7.总结1. 什么是分布式 ? 分布式系统一定是由多个节点组成的系统。 其中&#xff0c;节点指的是计算机服务器&#xff0c;而且这些节点一…...

MyBatis框架的入门案例

MyBatis框架的入门案例 资源地址&#xff1a;https://download.csdn.net/download/weixin_41957626/87531373 1.MyBatis的配置 环境&#xff1a;基于maven的结构 1.1目录结构 1.2依赖包 <dependencies><!--mybatis--><dependency><groupId>org.mybatis…...

红黑树-随记

文章目录1.为什么hashmap用红黑树不用二叉树和平衡二叉树1.1 二叉树&#xff08;Binary Search Tree&#xff09;1.2 红黑树&#xff08;Red Black Tree&#xff09;1.3 平衡二叉树&#xff08;Balence Binary Tree&#xff09;也称AVT2.为什么mysql用b数&#xff0c;不用B数或…...

Python异常处理更新,正常和不正常的都在这里

嗨害大家好鸭&#xff01;我是小熊猫~ 异常处理篇嗨害大家好鸭&#xff01;我是小熊猫~Python标准异常&#x1f4a8;什么是异常&#xff1f;不正常异常处理&#x1f4a8;使用except而不带任何异常类型使用except而带多种异常类型try-finally 语句异常的参数触发异常用户自定义异…...

[数据结构]:10-二叉排序树(无头结点)(C语言实现)

目录 前言 已完成内容 二叉排序树实现 01-开发环境 02-文件布局 03-代码 01-主函数 02-头文件 03-BinarySearchTreeCommon.cpp 04-BinarySearchTreeFunction.cpp 结语 前言 此专栏包含408考研数据结构全部内容&#xff0c;除其中使用到C引用外&#xff0c;全为C语言…...

openstack浅析

** OpenStack是一个由多个组件组成的开源云计算平台&#xff0c;每个组件都有不同的功能和用途。 ** 组件构成 以下是OpenStack中一些常见的组件及其功能&#xff1a; Nova&#xff1a;用于管理虚拟机的组件&#xff0c;提供了虚拟机的创建、销毁、管理等功能。 Neutron&am…...

华为OD机试Golang解题 - 特异性双端队列 | 含思路

华为Od必看系列 华为OD机试 全流程解析+经验分享,题型分享,防作弊指南)华为od机试,独家整理 已参加机试人员的实战技巧华为od 2023 | 什么是华为od,od 薪资待遇,od机试题清单华为OD机试真题大全,用 Python 解华为机试题 | 机试宝典文章目录 华为Od必看系列使用说明本期题目…...

代码随想录中:回溯算法的基础

回溯算法是一种暴力的搜索方式&#xff1b;回溯法一般与递归同时存在。 回溯法&#xff0c;一般可以解决如下几种问题&#xff1a; 组合问题&#xff1a;N个数里面按一定规则找出k个数的集合切割问题&#xff1a;一个字符串按一定规则有几种切割方式子集问题&#xff1a;一个…...

Android kotlin 系列讲解(进阶篇)Jetpack系列之LiveData

<<返回总目录 文章目录 一、LiveData是什么二、LiveData测试一、LiveData是什么 LiveData是Jetpack提供的一种响应式编程组件,它可以包括任何类型的数据,并在数据发生变化的时候通知给观察者。LiveData特别适合与ViewModel结合在一起使用,虽然它也可以单独在别的地方…...

如何判断有向无环图:构造有向无环图

拓扑序列&#xff1a;可以用来判断一个有向图是否有环&#xff01; 拓扑排序可以判断有向图是否存在环。我们可以对任意有向图执行上述过程&#xff0c;在完成后检查A序列的长度。 若A序列的长度小于图中点的数量&#xff0c;则说明某些节点未被遍历&#xff0c;进而说明图中存…...

【2022.1.3】手脱压缩壳练习(含练习exe)

【2022.1.3】手脱压缩壳练习&#xff08;含练习exe&#xff09; 文章目录【2022.1.3】手脱压缩壳练习&#xff08;含练习exe&#xff09;0、简介1、单步跟踪法&#xff08;#&#xff09;方法介绍&#xff08;0&#xff09;练习exe下载&#xff08;1&#xff09;、查看源程序&am…...

网络六边形受到攻击

大家读完觉得有帮助记得关注和点赞&#xff01;&#xff01;&#xff01; 抽象 现代智能交通系统 &#xff08;ITS&#xff09; 的一个关键要求是能够以安全、可靠和匿名的方式从互联车辆和移动设备收集地理参考数据。Nexagon 协议建立在 IETF 定位器/ID 分离协议 &#xff08;…...

python打卡day49

知识点回顾&#xff1a; 通道注意力模块复习空间注意力模块CBAM的定义 作业&#xff1a;尝试对今天的模型检查参数数目&#xff0c;并用tensorboard查看训练过程 import torch import torch.nn as nn# 定义通道注意力 class ChannelAttention(nn.Module):def __init__(self,…...

JavaScript 中的 ES|QL:利用 Apache Arrow 工具

作者&#xff1a;来自 Elastic Jeffrey Rengifo 学习如何将 ES|QL 与 JavaScript 的 Apache Arrow 客户端工具一起使用。 想获得 Elastic 认证吗&#xff1f;了解下一期 Elasticsearch Engineer 培训的时间吧&#xff01; Elasticsearch 拥有众多新功能&#xff0c;助你为自己…...

中南大学无人机智能体的全面评估!BEDI:用于评估无人机上具身智能体的综合性基准测试

作者&#xff1a;Mingning Guo, Mengwei Wu, Jiarun He, Shaoxian Li, Haifeng Li, Chao Tao单位&#xff1a;中南大学地球科学与信息物理学院论文标题&#xff1a;BEDI: A Comprehensive Benchmark for Evaluating Embodied Agents on UAVs论文链接&#xff1a;https://arxiv.…...

高等数学(下)题型笔记(八)空间解析几何与向量代数

目录 0 前言 1 向量的点乘 1.1 基本公式 1.2 例题 2 向量的叉乘 2.1 基础知识 2.2 例题 3 空间平面方程 3.1 基础知识 3.2 例题 4 空间直线方程 4.1 基础知识 4.2 例题 5 旋转曲面及其方程 5.1 基础知识 5.2 例题 6 空间曲面的法线与切平面 6.1 基础知识 6.2…...

selenium学习实战【Python爬虫】

selenium学习实战【Python爬虫】 文章目录 selenium学习实战【Python爬虫】一、声明二、学习目标三、安装依赖3.1 安装selenium库3.2 安装浏览器驱动3.2.1 查看Edge版本3.2.2 驱动安装 四、代码讲解4.1 配置浏览器4.2 加载更多4.3 寻找内容4.4 完整代码 五、报告文件爬取5.1 提…...

【C++特殊工具与技术】优化内存分配(一):C++中的内存分配

目录 一、C 内存的基本概念​ 1.1 内存的物理与逻辑结构​ 1.2 C 程序的内存区域划分​ 二、栈内存分配​ 2.1 栈内存的特点​ 2.2 栈内存分配示例​ 三、堆内存分配​ 3.1 new和delete操作符​ 4.2 内存泄漏与悬空指针问题​ 4.3 new和delete的重载​ 四、智能指针…...

Vue ③-生命周期 || 脚手架

生命周期 思考&#xff1a;什么时候可以发送初始化渲染请求&#xff1f;&#xff08;越早越好&#xff09; 什么时候可以开始操作dom&#xff1f;&#xff08;至少dom得渲染出来&#xff09; Vue生命周期&#xff1a; 一个Vue实例从 创建 到 销毁 的整个过程。 生命周期四个…...

Java后端检查空条件查询

通过抛出运行异常&#xff1a;throw new RuntimeException("请输入查询条件&#xff01;");BranchWarehouseServiceImpl.java // 查询试剂交易&#xff08;入库/出库&#xff09;记录Overridepublic List<BranchWarehouseTransactions> queryForReagent(Branch…...

何谓AI编程【02】AI编程官网以优雅草星云智控为例建设实践-完善顶部-建立各项子页-调整排版-优雅草卓伊凡

何谓AI编程【02】AI编程官网以优雅草星云智控为例建设实践-完善顶部-建立各项子页-调整排版-优雅草卓伊凡 背景 我们以建设星云智控官网来做AI编程实践&#xff0c;很多人以为AI已经强大到不需要程序员了&#xff0c;其实不是&#xff0c;AI更加需要程序员&#xff0c;普通人…...