CountDownLatch和CyclicBarrier源码详解

news/2024/7/5 2:29:39

 其他系列文章导航

Java基础合集

设计模式合集

多线程合集

分布式合集

ES合集


文章目录

  • 其他系列文章目录
  • 文章目录
  • 前言


前言

我现在有个场景:现在我有50个任务,这50个任务在完成之后,才能执行下一个函数,要是你,你怎么设计?

可以用JDK给我们提供的线程工具类,CountDownLatch和CyclicBarrier都可以完成这个需求。


一、CountDownLatch和CyclicBarrier

CountDownLatch允许一个或多个线程直等待,直到这些线程完成它们的操作。

而CyclicBarrier不一样,它往往是当线程到达某状态后,暂停下来等待其他线程等到所有线程均到达以后,才继续执行。

可以发现这两者的等待主体是不一样的。

CountDownLatch调用await()通常是主线程/调用线程,而CyclicBarrier调用await()是在任务线程调用的。

所以,CyclicBarrier中的阻塞的是任务的线程,而主线程是不受影响的。


二、CountDownLatch源码分析

CountDownLatch也是基于AQS实现的,它的实现机制很简单。

Java 中 AQS(AbstractQueuedSynchronizer)的 state 一般有以下值:

  1. 0:表示当前没有任何线程占有锁或者资源。

  2. 1:表示当前有一个线程占有锁或者资源。

  3. 大于等于 2:表示当前有多个线程占有锁或者资源,即存在竞争状态。

  4. 负数:表示当前有等待获取锁或者资源的线程,这些线程处于阻塞状态。

  5. 特殊值:AQS 实现类可以根据自己的需求自定义特殊的 state 值,例如 ReentrantLock 就使用了一个表示重入次数的 state 值。

当我们在构建CountDownLatch对象时,传入的值其实就会赋值给AQS的关键变量state。

执行countDown方法时,其实就是利用CAS将state -1。

执行await方法时,其实就是判断state是否为0,不为0则加入到队列中,将该线程66阻塞掉(除了头结点)。

因为头节点会一直自旋等待state为0,当state为0时,头节点把剩余的在队列中阻塞的节点也一并唤醒。


三、CyclicBarrier源码分析

回到CyclicBarrier代码也不难,重点也就是await方法。

从源码不难发现的是,它没有像CountDownLatch和ReentrantLock使用AQS的state变量,而CyclicBarrier是直接借助ReentrantLock加上Condition 等待唤醒的功能进而实现的。

在构建CyclicBarrier时,传入的值会赋值给CyclicBarrier内部维护count变量,也会赋值给parties变量(这是可以复用的关键)。

每次调用await时,会将count -1,操作count值是直接使用ReentrantLock来保证线程安全性。

如果count不为0,则添加则condition队列中。

如果count等于0时,则把节点从condition队列添加至AQS的队列中进行全部唤醒并且将parties的值重新赋值为count的值(实现复用)。


四、总结

CountDownlatch基于AQS实现,会将构造CountDownLatch的入参传递至statecountDown()就是在利用CAS将state减1,await)实际就是让头节点一直在等待state为0时,释放所有等待的线程。

CyclicBarrier则利用ReentrantLock和Condition,自身维护了count和parties变量。每次调用await将count-1,并将线程加入到condition队列上。等到count为0时,则将condition队列的节点移交至AQS队列,并全部释放。



http://lihuaxi.xjx100.cn/news/1840447.html

相关文章

计算机组成原理-虚拟存储器

文章目录 虚拟存储系统页式虚拟存储器存储器的层次化结构段式虚拟存储器段页式虚拟存储器 虚拟存储系统 将辅存中程序部分调入内存,程序其他待分待需要再调入内存 页式虚拟存储器 将辅存中的程序分页,将当前用得到的程序的页调入到主存中。 外存块号…

Django整合回顾

web应用 什么是web:通过web访问web应用程序,很方便,用户只需要一个浏览器即可。是典型的浏览器/服务器端架构的产物 cs架构与bs架构 应用程序有C/S B/S两种模式:b/s 本质上还是c/s mysql属于c/s架构,只是我们的服务…

Adversarial Attack and Defense on Graph Data: A Survey(2022 IEEE Trans)

Adversarial Attack and Defense on Graph Data: A Survey----《图数据的对抗性攻击和防御:综述》 图对抗攻击论文数据库: https://github.com/safe-graph/graph-adversarial-learning-literature 摘要 深度神经网络(DNN)已广泛应…

【论文阅读】TACAN:控制器局域网中通过隐蔽通道的发送器认证

文章目录 摘要一、引言二、相关工作三、系统和对手模型3.1 系统模型对手模型 四、TACAN4.1 TACAN 架构4.2 发送方认证协议4.3 基于IAT的隐蔽通道4.4 基于偏移的隐蔽通道(本节公式格式暂未整理)4.5 基于LSB的隐蔽通道 摘要 如今,汽车系统与现…

c语言练习12周(15~16)

编写int fun(char s[])函数,返回字串中所有数字累加和 题干编写int fun(char s[])函数,返回字串中所有数字累加和。 若传入串"k2h3yy4x"返回整数9;若传入串"uud9a6f7*"返回整数22 //只填写要求的函数 int fun(cha…

诺威信,浪潮云,微众区块链

目录 诺威信B隐私计算平台 浪潮云=星火连-澳优码 HyperChain 产品介绍 CA认证即电子认证服务

.NET6实现破解Modbus poll点表配置文件

📢欢迎点赞 :👍 收藏 ⭐留言 📝 如有错误敬请指正,赐人玫瑰,手留余香!📢本文作者:由webmote 原创📢作者格言:新的征程,我们面对的不仅仅是技术还有人心,人心不可测,海水不可量,唯有技术,才是深沉黑夜中的一座闪烁的灯塔 !序言 Modbus 协议是工控领域常见…

Python3 selenium 设置元素等待的三种方法

为什么要设置元素等待? 当你的网络慢的时候,打开网页慢,网页都没完全打开,代码已经在执行了,但是没找到你定位的元素,此时python会报错。 当你的浏览器或电脑反应慢,网页没完全打开,…