CountDownLatch 源码分析

CountDownLatch

(锁存器/闭锁)是基于同步器实现的同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待。
用计数值 N 初始化的 CountDownLatch 可以使一个或多个线程在其他 N 个线程完成某项操作之前一直等待,或者使其在某项操作完成 N 次之前一直等待。

创建实例

    private static final class Sync extends AbstractQueuedSynchronizer {
        private static final long serialVersionUID = 4982264981922014374L;

        Sync(int count) {
            // 写入状态值
            setState(count);
        }

        int getCount() {
            return getState();
        }

        /**
         *  只有当同步状态为 0 时才能获取成功,否则进入阻塞
         * created by ZXD at 15 Dec 2018 T 12:05:56
         * @param acquires
         * @return
         */
        @Override
        protected int tryAcquireShared(int acquires) {
            return getState() == 0 ? 1 : -1;
        }

        /**
         *  尝试将状态值递减 1,如果递减到 0,则释放在闭锁上阻塞等待的所有线程
         */
        @Override
        protected boolean tryReleaseShared(int releases) {
            // Decrement count; signal when transition to zero
            for (;;) {
                final int c = getState();
                if (c == 0) {
                    return false;
                }
                // 状态值递减 1
                final int nextc = c - 1;
                if (compareAndSetState(c, nextc)) {
                    // 已经递减到 0,则返回 true
                    return nextc == 0;
                }
            }
        }
    }

    private final Sync sync;

    /**
     *  创建计数值为 count 的闭锁
     */
    public CountDownLatch(int count) {
        if (count < 0) {
            throw new IllegalArgumentException("count < 0");
        }
        sync = new Sync(count);
    }

同步阻塞

    /**
     *  阻塞等待闭锁的状态值递减到 0、或线程被中断为止
     */
    public void await() throws InterruptedException {
        sync.acquireSharedInterruptibly(1);
    }

    /**
     *  在指定的超时时间内阻塞等待闭锁的状态值递减到 0、或线程被中断为止
     */
    public boolean await(long timeout, TimeUnit unit)
            throws InterruptedException {
        return sync.tryAcquireSharedNanos(1, unit.toNanos(timeout));
    }

递减闭锁状态值,如果递减到 0,则释放所有在闭锁上阻塞等待的线程

    /**
     *  递减闭锁状态值,如果递减到 0,则释放所有在闭锁上阻塞等待的线程
     */
    public void countDown() {
        sync.releaseShared(1);
    }

猜你喜欢

转载自www.cnblogs.com/zhuxudong/p/10122927.html