Java 并发编程(十三) -- CountDownLatch源码分析

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;
            }
        }
复制代码

猜你喜欢

转载自juejin.im/post/5e6edc76f265da573e673ffb