1. 类的定义
public class CountDownLatch
复制代码
2. 字段属性
//同步器,是AbstractQueuedSynchronizer的子类
private final Sync sync;
复制代码
从字段属性可以看出
- CountDownLatch的核心是内部类Sync,可以猜测出所有的操作都是通过Sync对象来操作的
3. 构造方法
public CountDownLatch(int count) {
//参数检查
if (count < 0) throw new IllegalArgumentException("count < 0");
//初始化Sync
this.sync = new Sync(count);
}
复制代码
从构造方法中可以看出
- 构造方法只做了一件事就是初始化Sync对象
4. 方法
await 方法
//等待,直到count到0再执行,或者线程被中断
public void await() throws InterruptedException {
//调用sync的acquireSharedInterruptibly方法进入等待
sync.acquireSharedInterruptibly(1);
}
//设置超时时间的等待
public boolean await(long timeout, TimeUnit unit)
throws InterruptedException {
//调用sync的tryAcquireSharedNanos方法进入等待
return sync.tryAcquireSharedNanos(1, unit.toNanos(timeout));
}
复制代码
countDown 方法
//count 减1
public void countDown() {
//调用sync的releaseShared方法
sync.releaseShared(1);
}
复制代码
getCount 方法
//获取count
public long getCount() {
//调用sync的getCount
return sync.getCount();
}
复制代码
toString 方法
public String toString() {
//可以看出打印了count的值
return super.toString() + "[Count = " + sync.getCount() + "]";
}
复制代码
从方法中可以看出Sync对象是一个共享锁
5. 内部类Sync
1. 类的定义
private static final class Sync extends AbstractQueuedSynchronizer
复制代码
从类的定义中可以看出
- Sync是CountDownLatch私有的静态内部类
- Sync继承了AbstractQueuedSynchronizer
2. 字段属性
//序列化版本号
private static final long serialVersionUID = 4982264981922014374L;
复制代码
3. 构造方法
//传入count
Sync(int count) {
//调用父类的setState方法
setState(count);
}
复制代码
从构造方法可以看出
- 传入的count就是AbstractQueuedSynchronizer的state方法
4. 方法
getCount 方法
//获取count,实际上就是获取state
int getCount() {
return getState();
}
复制代码
tryAcquireShared 方法
//尝试获取共享锁,重写父类方法,这个方法是让父类调用
protected int tryAcquireShared(int acquires) {
//如果state为0,返回1, 其他的返回-1
//小于0会尝试获取锁,如果获取锁失败则会进入队列等待被唤醒
return (getState() == 0) ? 1 : -1;
}
复制代码
tryReleaseShared 方法
//释放共享锁,这个参数没有意义,每次通过CAS自旋的方法让state-1
protected boolean tryReleaseShared(int releases) {
//无限for循环表示自旋
for (;;) {
//获取状态值
int c = getState();
//如果状态值为0, 表示已经完全释放锁了,直接返回false
if (c == 0)
return false;
//状态值不为0,让状态值-1,并用CAS设置新值
int nextc = c-1;
if (compareAndSetState(c, nextc))
return nextc == 0;
}
}
复制代码