首页 > 作文

CountDownLatch和Atomic原子操作类源码解析

更新时间:2023-04-06 02:59:05 阅读: 评论:0

引导语

本小节和大家一起来看看 countdownlatch 和 atomic 打头的原子操作类,countdownlatch 的源码非常少,看起来比较简单,但弘扬雷锋精神作文 countdownlatch 的实际应用却不是很容易;atomic 原子操作类就比较好理解和应用,接下来我们分别来看一下。

1、countdownlatch

countdownlatch 中文有的叫做计数器,也有翻译为计数锁,其最大的作用不是为了加锁,而是通过计数达到等待的功能,主要有两种形式的等待:

让一组线程在全部启动完成之后,再一起执行(先启动的线程需要阻塞等待后启动的线程,直到一组线程全部都启动完成后,再一起执行);主线程等待另外一组线程都执行完成之后,再继续执行。

我们会举一个示例来演示这两种情况,但在这之前,我们先来看看 countdownlatch 的底层源码实现,这样就会清晰一点,不然一开始就来看示例,估计很难理解。

countdownlatch 有两个比较重要的 api,分别是 await 和 countdown,管理着线程能否获得锁和锁的释放(也可以称为对 state 的计数增加和减少)。

1.1、await

await 我们可以叫做等待,也可以叫做加锁,有两种不同入参的方法,源码如下:

两个方法底层使用的都是 sync,sync 是一个同步器,是 countdownlatch 的内部类实现的,如下:

可以看出来 sync 继承了 abstractqueuedsynchronizer,具备了同步器的通用功能。

无参 await 底层使用的是 acquiresharedinterruptibly 方法,有参的使用的是 tryacquiresharednanos 方法,这两个方法都是 aqs 的方法,底层实现很相似,主要分成两步:

1.使用子类的 tryacquireshared 方法尝试获得锁,如果获取了锁直接返回,获取不到锁走 2;

2.获取不到锁,用 node 封装一下当前线程,追加到同步队列的尾部,等待在合适的时机去获得锁。

第二步是 aqs 已经实现了,第一步 tryacquireshared 方法是交给 sync 实现的,源码如下:

获得锁的代码也很简单,直接根据同步器的 state 字段来进行判断,但还是有两点需要注意一下:

获得锁时,state 的值不会发生变化,像 reentrantlock 在获得锁时,会把 state + 1,但 countdownlatch 不会;

countdownlatch 的 state 并不是 aqs 的默认值 0,而是可以赋值的,是在 countdownlatch 初始化的时候赋值的,

代码如下:

这里的初始化的 count 和一般的锁意义不太一样,count 表示我们希望等待的线程数,在两种不同的等待场景中,count 有不同的含义:

让一组线程在全部启动完成之后,再一起执行的等待场景下, count 代表一组线程的个数;

主线程等待另外一组线程都执行完成之后,再继续执行的等待场景下,count 代表一组线程的个数。

所以我们可以把 count 看做我们希望等待的一组线程的个数,可能我们是等待一组线程全部启动完成,可能我们是等待一组线程全部执行完成。

1.2、countdown

countdown 中文翻译为倒计时,每调用一次,都会使 state 减一,底层调用的方法如下:

releashared 是 a团支部书记职责qs 定义的方法,方法主要分成两步:

1.尝试释放锁(tryreleashared),锁释放失败直接返回,释放成功走2

2.释放当前节点的后支委会内容置等待节点。

第二步 aqs 已经实现了,第一步是 sync 实现的,我们一起来看下 tryreleashared 方法的实现源码:

从源码中可以看到,只有到 count 递减到 0 时,countdown 才会返回 true。

1.3、示例

看完 countdownlatch 两个重要 api 后,我们来实现文章开头说的两个功能:

让一组线程在全部启动完成之后,再一起执行;

主线程等待另外一组线程都执行完成之后,再继续执行。

代码在 countdownlatchdemo 类中,大家可以调试看看,源码如下:

从执行结果中,可以看出已经实现了以上两个功能,实现比较绕,大家可以根据注释,debug 看一看。

2、atomic 原子操作类

atomic 打头的原子操作类有很多,涉及到 java 常用的数字类型的,基本都有相应的 atomic 原子操作类,如下图所示:

atomic 打头的原子操作类,在高并发场景下,都是线程安全的,我们可以放心使用。

我们以 atomicinteger 为例子,来看下主要的底层实现:

从源码中,我们可以看到,线程安全的操作方法,底层都是使用 unsafe 方法实现,以上几个 unsafe 方法不是使用 java 实现的,都是线程安全的怎样治疗近视眼。

atomicinteger 是对 int 类型的值进行自增自减,那如果 atomic 的对象是个自定义类怎么办呢,java 也提供了自定义对象的原子操作类,叫做 atomicreference。atomicreference 类可操作的对象是个泛型,所以支持自定义类,其底层是没有自增方法的,操作的方法可以作为函数入参传递,源码如下:

3、总结

countdown20个元音音标latch 的源码实现简单,但真的要用好还是不简单的,其使用场景比较复杂,建议同学们可以 debug 一下

countdownlatchdemo,在增加实战能力基础上,增加底层的理解能力。

以上就是countdownlatch和atomic原子操作类源码解析的详细内容,更多关于countdownlatch和atomic原子操作类的资料请关注www.887551.com其它相关文章!

本文发布于:2023-04-06 02:59:03,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/zuowen/36056baa52dee7b3bc7113837098cf19.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

本文word下载地址:CountDownLatch和Atomic原子操作类源码解析.doc

本文 PDF 下载地址:CountDownLatch和Atomic原子操作类源码解析.pdf

标签:线程   方法   源码   原子
相关文章
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图