美文网首页
CountDownLatch的使用

CountDownLatch的使用

作者: 永远的太阳0123 | 来源:发表于2019-01-12 16:58 被阅读0次

    1 CountDownLatch

    CountDownLatch.Sync继承了AbstractQueuedSynchronizer,重写了tryAcquireShared方法和tryReleaseShared方法。

    public class CountDownLatch {
    
        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) {
                for (;;) {
                    int c = getState();
                    if (c == 0)
                        return false;
                    int nextc = c-1;
                    if (compareAndSetState(c, nextc))
                        return nextc == 0;
                }
            }
        }
    
        private final Sync sync;
    
        public CountDownLatch(int count) {
            if (count < 0) throw new IllegalArgumentException("count < 0");
            this.sync = new Sync(count);
        }
    
        public void await() throws InterruptedException {
            sync.acquireSharedInterruptibly(1);
        }
    
        public boolean await(long timeout, TimeUnit unit)
            throws InterruptedException {
            return sync.tryAcquireSharedNanos(1, unit.toNanos(timeout));
        }
    
        public void countDown() {
            sync.releaseShared(1);
        }
    
        public long getCount() {
            return sync.getCount();
        }
    
        public String toString() {
            return super.toString() + "[Count = " + sync.getCount() + "]";
        }
    }
    

    2 CountDownLatch图解

    state大于0时,所有调用了await方法的线程都会被阻塞;state等于0时,所有被阻塞的线程一起通过栅栏。


    3 CountDownLatch使用案例1

    3.1 Driver

    public class Driver1 {
    
        public static void main(String[] args) {
    
            CountDownLatch startSignal = new CountDownLatch(1);
            CountDownLatch doneSignal = new CountDownLatch(10);
    
            for (int i = 0; i < 10; i++)
                new Thread(new Worker1(startSignal, doneSignal)).start();
    
            sleep(1);
            System.out.println("开始执行任务");
            startSignal.countDown();
            try {
                doneSignal.await();
                System.out.println("已完成所有任务");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
    
        }
    
        public static void sleep(int second) {
            try {
                TimeUnit.SECONDS.sleep(second);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    
    }
    

    3.2 Worker

    public class Worker1 implements Runnable {
    
        private final CountDownLatch startSignal;
        private final CountDownLatch doneSignal;
    
        public Worker1(CountDownLatch startSignal, CountDownLatch doneSignal) {
            super();
            this.startSignal = startSignal;
            this.doneSignal = doneSignal;
        }
    
        @Override
        public void run() {
            try {
                startSignal.await();
                doWork();
                doneSignal.countDown();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    
        void doWork() {
            try {
                TimeUnit.SECONDS.sleep(1);
                System.out.println(Thread.currentThread().getName() + ": 已完成任务");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    
    }
    

    4 CountDownLatch使用案例2

    4.1 Driver

    public class Driver2 {
    
        public static void main(String[] args) {
            CountDownLatch doneSignal = new CountDownLatch(10);
            Executor e = Executors.newFixedThreadPool(5);
    
            for (int i = 1; i <= 10; i++)
                e.execute(new Worker2(doneSignal, i));
    
            try {
                doneSignal.await();
                System.out.println("已完成所有任务");
            } catch (InterruptedException e1) {
                e1.printStackTrace();
            }
        }
    
    }
    

    4.2 Worker

    public class Worker2 implements Runnable {
    
        private final CountDownLatch doneSignal;
        private final int i;
    
        Worker2(CountDownLatch doneSignal, int i) {
            this.doneSignal = doneSignal;
            this.i = i;
        }
    
        @Override
        public void run() {
            doWork(i);
            doneSignal.countDown();
        }
    
        void doWork(int i) {
            try {
                TimeUnit.SECONDS.sleep(1);
                System.out.println(Thread.currentThread().getName() + ": 已完成第" + i + "项任务");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    
    }
    

    相关文章

      网友评论

          本文标题:CountDownLatch的使用

          本文链接:https://www.haomeiwen.com/subject/mvecdqtx.html