CountDownLatch源码分析

来源:互联网 发布:电话号码扫描录入软件 编辑:程序博客网 时间:2024/06/16 11:19
package java.util.concurrent;import java.util.concurrent.locks.AbstractQueuedSynchronizer;public class CountDownLatch {    /**     * Synchronization control For CountDownLatch.     * Uses AQS state to represent count. *  * 用AbstractQueuedSynchronizer的状态来表示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) {            return (getState() == 0) ? 1 : -1;        }        protected boolean tryReleaseShared(int releases) {            // Decrement count; signal when transition to zero            for (;;) {                int c = getState();                if (c == 0)                    return false;                int nextc = c-1;                if (compareAndSetState(c, nextc))                    return nextc == 0;            }        }    }    private final Sync sync;// 构造一个等待线程数量为count的闭锁。注:count的值一旦设定就不可以更改了。    public CountDownLatch(int count) {        if (count < 0) throw new IllegalArgumentException("count < 0");        this.sync = new Sync(count);    }    /**     * Causes the current thread to wait until the latch has counted down to zero, unless the thread is interrupted.     *     * If the current count is greater than zero then the current thread becomes disabled for thread scheduling purposes  * and lies dormant until one of two things happen:     * The count reaches zero due to invocations of the {@link #countDown} method;     * Some other thread {@linkplain Thread#interrupt interrupts} the current thread.     */// 线程调用await()方法,进入等待状态。    public void await() throws InterruptedException {        sync.acquireSharedInterruptibly(1);    }// -------------------- 补充:AbstractQueuedSynchronizer 中的方法 ----------------------------------------////public final void acquireSharedInterruptibly(int arg) throws InterruptedException {//if (Thread.interrupted())//throw new InterruptedException();//if (tryAcquireShared(arg) < 0) // 获取锁失败//doAcquireSharedInterruptibly(arg);//}////private void doAcquireSharedInterruptibly(int arg) throws InterruptedException {//            final Node node = addWaiter(Node.SHARED);//            boolean failed = true;//            try {//                for (;;) {// 开始自旋//                    final Node p = node.predecessor();//                    if (p == head) {//                        int r = tryAcquireShared(arg);//                        if (r >= 0) {//                            setHeadAndPropagate(node, r);//                            p.next = null; // help GC//                            failed = false;//                            return;//                        }//                    }//                    if (shouldParkAfterFailedAcquire(p, node) && parkAndCheckInterrupt())//                        throw new InterruptedException();//                }//            } finally {//                if (failed) cancelAcquire(node);//            }//    }//// -------------------- 补充:AbstractQueuedSynchronizer 中的方法 ----------------------------------------    public boolean await(long timeout, TimeUnit unit)        throws InterruptedException {        return sync.tryAcquireSharedNanos(1, unit.toNanos(timeout));    }    /**     * Decrements the count of the latch, releasing all waiting threads if the count reaches zero.     * If the current count equals zero then nothing happens.     */    public void countDown() {        sync.releaseShared(1);    }// -------------------- 补充:AbstractQueuedSynchronizer 中的方法 ----------------------------------------////    public final boolean releaseShared(int arg) {//        if (tryReleaseShared(arg)) {//            doReleaseShared();//            return true;//        }//        return false;//    }////    private void doReleaseShared() {//        /*//         * Ensure that a release propagates, even if there are other//         * in-progress acquires/releases.  This proceeds in the usual//         * way of trying to unparkSuccessor of head if it needs//         * signal. But if it does not, status is set to PROPAGATE to//         * ensure that upon release, propagation continues.//         * Additionally, we must loop in case a new node is added//         * while we are doing this. Also, unlike other uses of//         * unparkSuccessor, we need to know if CAS to reset status//         * fails, if so rechecking.//         *///        for (;;) {//            Node h = head;//            if (h != null && h != tail) {//                int ws = h.waitStatus;//                if (ws == Node.SIGNAL) {//                    if (!compareAndSetWaitStatus(h, Node.SIGNAL, 0))//                        continue;            // loop to recheck cases//                    unparkSuccessor(h);//                }//                else if (ws == 0 &&//                         !compareAndSetWaitStatus(h, 0, Node.PROPAGATE))//                    continue;                // loop on failed CAS//            }//            if (h == head)                   // loop if head changed//                break;//        }//    }//// -------------------- 补充:AbstractQueuedSynchronizer 中的方法 ----------------------------------------    /**     * Returns the current count.     */    public long getCount() {        return sync.getCount();    }}

原创粉丝点击