java并发编程CountDownLatch类源码解析

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java并发编程CountDownLatch类源码解析相关的知识,希望对你有一定的参考价值。

记录一下,今天学java并发编程的工具类写一下自己对CountDownLatch 类的理解
类本身的作用,类似于waitnotify,使线程进入阻塞并唤醒,达到线程通信的目的,
看一下实现原理

技术分享图片

内部使用了同步类容器也就是AQS,Sync对象 ,count参数是指多线程需要唤醒的次数,内部维护了一个state属性就是count传入的属性, 可以当作一个计数器,如果为负数会抛出参数异常 。 然后实例化sync对象。

![](http://i2.51cto.com/images/blog/201811/21/de976d787751fa897a6867495b8747c4.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=)

线程阻塞方法

技术分享图片

判断线程是否是中断,如果中断抛出异常,正常情况下不会中断

技术分享图片

主要调用tryAcquireShared方法 判断state的值是否为0,0则返回1表示该线程被唤醒该判断的意义在于 “进入阻塞时先尝试一次是否可以被立即唤醒,如果能则继续执行,是非公平操作会先抢占一次资源,如果是公平操作则直接进入等待队列 ”

技术分享图片

接下来调用 doAcquireSharedInterruptibly 方法的addWaiter 将线程进行入队列(因为会存在多个线程进入阻塞) 唤醒时根据先进先出的顺序依次唤醒,队列为链表结构将其加入到最后一个节点中。

然后线程进for循环空转的阻塞状态,首先判断等待队列的头节点是否是当前线程 ,是则在调用tryAcquireShared判断是否被唤醒如果唤醒则在队列中删除当前线程,继续执行程序,其他for循环中的阻塞线程也会依照队列依次唤醒。 parkAndCheckInterrupt 方法内部则中断线程调用释放资源保证程序性能 。

线程阻塞方法结束, 下面看一下countDown线程唤醒方法
技术分享图片
技术分享图片

该方法调用了 tryReleaseShared 进行State的减一

技术分享图片

重点 ,同步类容器通过用CAS方法保证原子性操作,回调用 compareAndSetState 尝试将期望值改为 State-1后的值,该方法不会阻塞,如果此时存在并发操作则返回false,for循环继续调用直到该操作成功 。如果state为0时表示唤醒成功 ,其余阻塞线程根据队列一次调用。

以上是关于java并发编程CountDownLatch类源码解析的主要内容,如果未能解决你的问题,请参考以下文章

Java并发编程-CountDownLatch

Java Review - 并发编程_ CountDownLatch原理&源码剖析

java并发编程之CountDownLatch与CyclicBarrier

并发编程技术六之共享锁CountDownLatch源码分析

每日一博 - CountDownLatch使用场景分析以及源码分析

『死磕Java并发编程系列』并发编程工具类之CountDownLatch