当前位置:首页软件开发Java → Jdk1.6 JUC源码解析(9)-CountDownLatch

Jdk1.6 JUC源码解析(9)-CountDownLatch

时间:2020-12-10 00:36:37来源:互联网我要评论(0)

   Jdk1.6 JUC源码解析(9)-CountDownLatch

 

功能简介: 源码分析:

    /**
     * CountDownLatch内部同步器,利用AQS的state来表示count。
     */
    private static final class Sync extends AbstractQueuedSynchronizer {
        private static final long serialVersionUID = 4982264981922014374L;
        Sync(int count) {
            setState(count);
        }
        int getCount() {
            return getState();
        }

        protected int tryAcquireShared(int acquires) {
            //如果当前count为0,那么方法返回1,
            //按照之前对AQS的分析,请求成功,并唤醒同步队列里下一个共享模式的线程(这里都是共享模式的)。
            //如果当前count不为0,那么方法返回-1,请求失败,当前线程最终会被阻塞(之前会不止一次调用tryAcquireShared)。
            return getState() == 0? 1 : -1;
        }
        protected boolean tryReleaseShared(int releases) {
            // 如果count为0,返回false,相当于释放失败,因为此时闭锁处于开放状态,没有必要在打开。
            // 如果count不为0,递减count。
            // 最后如果count为0,说明关闭的闭锁打开了,那么返回true,后面会唤醒等待队列中的线程。
            // 如果count不为0,说明闭锁还是处于关闭状态,返回false。
            for (;;) {
                int c = getState();
                if (c == 0)
                    return false;
                int nextc = c-1;
                if (compareAndSetState(c, nextc))
                    return nextc == 0;
            }
        }
    }

 

public class CountDownLatch {
    private final Sync sync;
    
    ...
    /**
     * 根据给定的count创建一个CountDownLatch。
     */
    public CountDownLatch(int count) {
        if (count < 0) throw new IllegalArgumentException("count < 0");
        this.sync = new Sync(count);
    }
    /**
     * 如果当前count为0,那么方法立即返回。
     *
     * 如果当前count不为0,那么当前线程会一直等待,直到count被(其他线程)减到0或者当前线程被中断。
     */
    public void await() throws InterruptedException {
        sync.acquireSharedInterruptibly(1);
    }
    /**
     * 如果当前count为0,那么方法立即返回true。
     *
     * 如果当前count不为0,那么当前线程会一直等待,直到count被(其他线程)减到0或者当前线程被中断或者超时。
     * 成功返回true,超时返回false,被中断抛异常。
     */
    public boolean await(long timeout, TimeUnit unit)
        throws InterruptedException {
        return sync.tryAcquireSharedNanos(1, unit.toNanos(timeout));
    }
    /**
     * 如果当前count大于0,递减count。如果递减后,count等于0,那么AQS中所有等待线程都被唤醒。
     *
     * 如果当前count等于0,什么事都不会发生。
     */
    public void countDown() {
        sync.releaseShared(1);
    }
    /**
     * 获取当前count值。
     */
    public long getCount() {
        return sync.getCount();
    }
    /**
     * Returns a string identifying this latch, as well as its state.
     * The state, in brackets, includes the String {@code "Count ="}
     * followed by the current count.
     *
     * @return a string identifying this latch, as well as its state
     */
    public String toString() {
        return super.toString() + "[Count = " + sync.getCount() + "]";
    }
}

 

       小总结一下:

              1.建立一个count为n的闭锁后,闭锁的内部计数为n,这时如果有线程调用闭锁的await方法,会阻塞。               2.每一次调用闭锁的countDown方法,内部计数就会减1,当闭锁的countDown方法被调用n次后,内部计数减为0,这时在闭锁await方法上等待的线程就被唤醒了。  

       CountDownLatch的代码解析完毕!

 

 

       参见:Jdk1.6 JUC源码解析(6)-locks-AbstractQueuedSynchronizer

 

 

相关文章

网友评论

热门评论

最新评论

发表评论 查看所有评论()

昵称:
表情: 高兴 可 汗 我不要 害羞 好 下下下 送花 屎 亲亲
字数: 0/500 (您的评论需要经过审核才能显示)

关于万荚 | 联系方式 | 发展历程 | 版权声明 | 帮助(?) | 网站地图 | 友情链接

Copyright 2005-2020 16WJ.COM 〖万荚网〗 版权所有 桂ICP备18000060号 |

声明: 本站所有文章来自互联网 如有异议 请与本站联系