Java多线程深入学习-CountDownLatch源码解析

其内部就是用一个实现AQS的同步器进行处理,重写了tryAcquireShared和tryReleaseShared方法,这里就直接上源码吧

/**
 * 一种同步辅助工具,允许一个或多个线程等待其他线程中正在执行的一组操作完成
 * @since 1.5
 * @author Doug Lea
 */
public class CountDownLatch {
    /**
     * 定义静态内部类(同步器)继承AQS
     */
    private static final class Sync extends AbstractQueuedSynchronizer {
        private static final long serialVersionUID = 4982264981922014374L;

        //初始化同步器,指定state值
        Sync(int count) {
            setState(count);
        }

        //获取当前state值
        int getCount() {
            return getState();
        }

        //尝试获取共享锁
        protected int tryAcquireShared(int acquires) {
            return (getState() == 0) ? 1 : -1;
        }

        //尝试释放共享锁
        protected boolean tryReleaseShared(int releases) {
            for (;;) {	//死循环
                int c = getState();	//获取当前state
                if (c == 0)		//若为0直接返回
                    return false;
                int nextc = c-1;	//计算目标值
                if (compareAndSetState(c, nextc))	//cas操作,操作失败会重新操作
                    return nextc == 0;	//操作成功,返回结果    
            }
        }
    }

    //同步器
    private final Sync sync;

    /**
     * 构造方法
     */
    public CountDownLatch(int count) {
        if (count < 0) throw new IllegalArgumentException("count < 0");	//校验count
        this.sync = new Sync(count);	//创建同步器,并赋值给sync
    }

    /**
     * 让当前线程进入等待
     */
    public void await() throws InterruptedException {
    	//获取共享锁  这里的做法就是Sync.tryAcquireShared
        sync.acquireSharedInterruptibly(1);
    }

    /**
     * 让当前线程进入等待  指定超时时间
     */
    public boolean await(long timeout, TimeUnit unit)
        throws InterruptedException {
        return sync.tryAcquireSharedNanos(1, unit.toNanos(timeout));
    }

    /**
     * 释放一个  也就是state - 1    cas操作
     */
    public void countDown() {
        sync.releaseShared(1);
    }

    /**
     * 获取当前state数
     */
    public long getCount() {
        return sync.getCount();
    }

    public String toString() {
        return super.toString() + "[Count = " + sync.getCount() + "]";
    }
}

猜你喜欢

转载自blog.csdn.net/luo_mu_hpu/article/details/108223156