zoukankan      html  css  js  c++  java
  • 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() + "]";
        }
    }
  • 相关阅读:
    Java 面试 --- 3
    Java 面试-- 1
    面试之痛 -- 二叉树 前序 中序 后序
    java 事务
    深入理解mybatis
    hibernate
    mybatis 原理
    spring 原理
    spring aop
    spring 事务
  • 原文地址:https://www.cnblogs.com/yaowen/p/11351930.html
Copyright © 2011-2022 走看看