zoukankan      html  css  js  c++  java
  • 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);
        }
    
  • 相关阅读:
    17年day4
    11.7NOIP模拟题
    P3389 【模板】高斯消元法
    洛谷 P2136 拉近距离 题解
    浅谈SPFA判负环
    洛谷 P1629 邮递员送信 题解
    洛谷 P1821 [USACO07FEB]银牛派对Silver Cow Party 题解
    洛谷 P3905 道路重建 题解
    洛谷 P1351 联合权值 题解
    洛谷 P4779 【模板】单源最短路径(标准版) 题解
  • 原文地址:https://www.cnblogs.com/zhuxudong/p/10122927.html
Copyright © 2011-2022 走看看