#yyds干货盘点# CountDownLatch详解

金鞍玉勒寻芳客,未信我庐别有春。这篇文章主要讲述#yyds干货盘点# CountDownLatch详解相关的知识,希望能为你提供帮助。
CountDownLatch详解
CountDownLatch介绍
从源码可知,其底层是由AQS提供支持,所以其数据结构可以参考AQS的数据结构,而AQS的数据结构核心就是两个虚拟队列: 同步队列sync queue 和条件队列condition queue,不同的条件会有不同的条件队列。CountDownLatch典型的用法是将一个程序分为n个互相独立的可解决任务,并创建值为n的CountDownLatch。当每一个任务完成时,都会在这个锁存器上调用countDown,等待问题被解决的任务调用这个锁存器的await,将他们自己拦住,直至锁存器计数结束。
CountDownLatch源码分析
类的继承关系
CountDownLatch没有显示继承哪个父类或者实现哪个父接口, 它底层是AQS是通过内部类Sync来实现的。

public class CountDownLatch

类的内部类
CountDownLatch类存在一个内部类Sync,继承自AbstractQueuedSynchronizer,其源代码如下。
private static final class Sync extends AbstractQueuedSynchronizer
// 版本号
private static final long serialVersionUID = 4982264981922014374L;

// 构造器
Sync(int count)
setState(count);


// 返回当前计数
int getCount()
return getState();


// 试图在共享模式下获取对象状态
protected int tryAcquireShared(int acquires)
return (getState() == 0) ? 1 : -1;


// 试图设置状态来反映共享模式下的一个释放
protected boolean tryReleaseShared(int releases)
// Decrement count; signal when transition to zero
// 无限循环
for (; ; )
// 获取状态
int c = getState();
if (c == 0) // 没有被线程占有
return false;
// 下一个状态
int nextc = c-1;
if (compareAndSetState(c, nextc)) // 比较并且设置成功
return nextc == 0;




说明: 对CountDownLatch方法的调用会转发到对Sync或AQS的方法的调用,所以,AQS对CountDownLatch提供支持。
类的属性
可以看到CountDownLatch类的内部只有一个Sync类型的属性:
public class CountDownLatch
// 同步队列
private final Sync sync;


类的构造函数
public CountDownLatch(int count)
if (count < 0) throw new IllegalArgumentException("count < 0");
// 初始化状态数
this.sync = new Sync(count);


说明: 该构造函数可以构造一个用给定计数初始化的CountDownLatch,并且构造函数内完成了sync的初始化,并设置了状态数。
核心函数 - await函数
此函数将会使当前线程在锁存器倒计数至零之前一直等待,除非线程被中断。其源码如下
public void await() throws InterruptedException
// 转发到sync对象上
sync.acquireSharedInterruptibly(1);


说明: 由源码可知,对CountDownLatch对象的await的调用会转发为对Sync的acquireSharedInterruptibly(从AQS继承的方法)方法的调用。
acquireSharedInterruptibly源码如下:
public final void acquireSharedInterruptibly(int arg)
throws InterruptedException
if (Thread.interrupted())
throw new InterruptedException();
if (tryAcquireShared(arg) < 0)
doAcquireSharedInterruptibly(arg);


【#yyds干货盘点# CountDownLatch详解】说明: 从源码中可知,acquireSharedInterruptibly又调用了CountDownLatch的内部类Sync的tryAcquireShared和AQS的doAcquireSharedInterruptibly函数。

    推荐阅读