Java高并发同步组件之CountDownLatch源码解析

从本篇开始,将介绍JUC下面的一些常用的并发组件,今天先来看看最简单的CountDownLatch类。

CountDownLatch是一个倒计数器,其类很简单,内部有一个Sync类,该类继承自AQS类。类图如下所示:

从类图可以看出,CountDownLatch的核心API就两个,分别是await方法和CountDown方法。下面我们来看看其源码:

1、构造方法

构造方法需要传入一个次数count,然后再构造函数中将count传递给内部类Sync,来看看内部Sync类。从Sync类可以看出,传递进去的count进行设置AQS的state值。

2、await方法

调用CountDownLatch的await方法,当前线程会阻塞,直到CountDownLatch对象调用countDown方法将state值减到0。或者其他线程调用了当前线程的interrupt方法来中断该线程。await方法的源码如下所示:

从源码可以看出,await方法调用的是AQS中的acquireSharedInterruptibly方法。接下来去AQS中看看这个方法的源码:

从源码可以看出,acquireSharedInterruptibly响应线程中断的方法,如果被中断,则抛出异常。否则,调用tryAcquireShared方法,该方法在AQS是抽象方法,这里被内部类Sync类实现了。源码如下:

从源码可以看出,tryAcquireShared方法就是判断当前AQS中的state是否为0。此外,还有给await方法,可以传入timeout参数,该方法支持最大等待时间,到了最大等待时间则会抛出异常,这里不详细叙述。

3、countDown方法

countDown方法是将state的值减一。如果state为0,则唤醒调用await阻塞的线程。我们来看看源码:

从源码可以看出,countDown方法是调用AQS的releaseShared方法,同时设置参数为1。我们进去看看源码:

tryReleaseShared方法在AQS中是抽象的,这里在内部类Sync中实现了。源码如下:

从源码可以看出,tryReleased方法是一个死循环,其首先查看state值是否为0,如果为0,则直接返回。否则进行CAS自旋,将state值设置为减一。直到CAS成功了,才能返回。这里面的compareAndsetState方法底层调用的是Unsafe对象的方法进行设置。

总结

1、CountDownLatch这个类比较简介,是一个倒计数器,其构造函数传入count代表并发次数。每个线程调用一次countDown将count减一。最核心的两个方法是await和countDown。

2、线程调用await方法阻塞自己,直到countDown将count减到0。

3、CountDownLatch还是基于AQS实现的,类似于ReentrantLock。只是可重入锁将state加1,而次数将state减一。

小编整理了一些java进阶学习资料和面试题,需要资料的请加JAVA高阶学习Q群:730379855 这是小编创建的java高阶学习交流群,加群一起交流学习深造。群里也有小编整理的2019年最新最全的java高阶学习资料!

猜你喜欢

转载自blog.csdn.net/weixin_44157163/article/details/87803004