CountDownLatch源码

public class CountDownLatchExample1 {
    public static void main(String[] args) throws Exception {
        ExecutorService exec = Executors1.newCachedThreadPool();
        final CountDownLatch1 countDownLatch = new CountDownLatch1(3);
        for (int i = 0; i < 2; i++) {
            exec.execute(() -> {
                try {
                    System.out.println("我我我我我我");
                } catch (Exception e) {
                } finally {
                    //state=0(不能向下减了,这个线程继续向下执行完,就不管CountDownLatch了,),减1之后!=0继续向下执行完。
                    //减1之后=0唤醒队列下一个节点。队列中只有main线程,实例化的线程不会去排队,只会执行完。
                    countDownLatch.countDown();// 为了保证必须减一,写在finally里面
                }
            });
        }//线程在这里已经执行完了,
        
        //state=0  main线程就向下执行,state!=0 main线程去排队。
        countDownLatch.await(); // 减为0了才继续执行,这么多线程都减完了在一起走。
        exec.shutdown(); // 线程次用完要关闭
    }
}
//共享锁(不是锁,只是说多线程可以同时执行),没有锁的概念,没有公平非公平之分,
public class CountDownLatch1 {
    private static final class Sync extends AbstractQueuedSynchronizer1 {
        private static final long serialVersionUID = 4982264981922014374L;

        Sync(int count) {
            setState(count);//设置state
        }

        int getCount() {
            return getState();
        }

        // 这个方法会经常调用,如果state=0,证明可以唤醒等待线程了
        protected int tryAcquireShared(int acquires) {
            return (getState() == 0) ? 1 : -1;
        }

        // 尝试去释放锁,调用CountDown()方法会调用此方法,将state-1
        protected boolean tryReleaseShared(int releases) {
            for (;;) {// 死循环
                int c = getState();
                //一个是没减之前=0,一个是减1之后=0。没减之前=0就什么都不管了这个线程执行完算了。减1之后=0表示CountDownLatch变成了0就要唤醒主线程继续向下走。
                if (c == 0)
                    return false;//state=0不能向下减了,这个线程继续向下执行完,就不管CountDownLatch了,
                int nextc = c-1;
                if (compareAndSetState(c, nextc))//state减1失败继续死循环,
                    return nextc == 0;//true:唤醒队列下一个节点(已经减完了,唤醒main线程),false:减1后继续向下执行完
            }
        }
    }

    private final Sync sync;

    public CountDownLatch1(int count) {
        if (count < 0) throw new IllegalArgumentException("count < 0");
        this.sync = new Sync(count);
    }

    public void await() throws InterruptedException {
        sync.acquireSharedInterruptibly(1);//state=0 main线程就向下执行,state!=0 mian线程去排队。
    }

    public boolean await(long timeout, TimeUnit unit)
        throws InterruptedException {
        return sync.tryAcquireSharedNanos(1, unit.toNanos(timeout));
    }

    public void countDown() {
        //state=0(不能向下减了,这个线程继续向下执行完,就不管CountDownLatch了,),减1之后!=0继续向下执行完,不唤醒main线程。
        //减1之后=0唤醒队列下一个节点。队列中只有main线程,实例化的线程不会去排队,只会执行完。
        sync.releaseShared(1);
    }

    public long getCount() {
        return sync.getCount();
    }

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

 

posted @ 2019-08-14 14:56  无天666  阅读(218)  评论(0编辑  收藏  举报