美文网首页
CountDownLatch

CountDownLatch

作者: lucode | 来源:发表于2017-09-11 20:10 被阅读5次

    CountDownLatch是什么?

    CountDownLatch是在java1.5被引入的,跟它一起被引入的并发工具类还有CyclicBarrier、Semaphore、ConcurrentHashMap和BlockingQueue;
    它们都存在于java.util.concurrent包下。

    CountDownLatch能做什么?

    CountDownLatch这个类能够使一个线程等待其他线程完成各自的工作后再执行。

    public class CountDownLatchSample {
        /**
         * 计数器,用来控制线程
         * 传入参数2,表示计数器计数为2
         */
        private final static CountDownLatch mCountDownLatch = new CountDownLatch(2);
        /**
         * 示例工作线程类
         */
        private static class WorkingThread extends Thread {
            private final String mThreadName;
            private final int mSleepTime;
            public WorkingThread(String name, int sleepTime) {
                mThreadName = name;
                mSleepTime = sleepTime;
            }
            @Override
            public void run() {
                System.out.println("[" + mThreadName + "] started!");
                try {
                    Thread.sleep(mSleepTime);
                    // 执行一次 count 减一
                    mCountDownLatch.countDown();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
    
                System.out.println("[" + mThreadName + "] end!");
            }
        }
        /**
         * 示例线程类
         */
        private static class SampleThread extends Thread {
            @Override
            public void run() {
                try {
    
                    System.out.println("主线程开始等待");
                    // 会在这里堵塞,直到 count 为0 或者超时时间达到4秒
                    mCountDownLatch.await(4000, TimeUnit.MILLISECONDS);
                    System.out.println("主线程结束等待");
                } catch (InterruptedException e) {
    
                }
            }
        }
        public static void main(String[] args) throws Exception {
            // 最先run SampleThread
            new SampleThread().start();
            // 运行两个工作线程
            // 工作线程1运行5秒
            new WorkingThread("线程一", 5000).start();
            // 工作线程2运行2秒
            new WorkingThread("线程二", 2000).start();
    
        }
    }
    

    CountDownLatch内部如何实现的?

    CountDownLatch是通过一个计数器来实现的,计数器的初始值为线程的数量。每当一个线程完成了自己的任务后,计数器的值就会减1。当计数器值到达0时,它表示所有的线程已经完成了任务,然后在闭锁上等待的线程就可以恢复执行任务。

    原理图.png

    构造器中的计数值(count)实际上就是闭锁需要等待的线程数量。这个值只能被设置一次,而且CountDownLatch没有提供任何机制去重新设置这个计数值。
    与CountDownLatch的第一次交互是主线程等待其他线程。主线程必须在启动其他线程后立即调用CountDownLatch.await()方法。这样主线程的操作就会在这个方法上阻塞,直到其他线程完成各自的任务。
    其他N 个线程必须引用闭锁对象,因为他们需要通知CountDownLatch对象,他们已经完成了各自的任务。这种通知机制是通过 CountDownLatch.countDown()方法来完成的;每调用一次这个方法,在构造函数中初始化的count值就减1。所以当N个线程都调 用了这个方法,count的值等于0,然后主线程就能通过await()方法,恢复执行自己的任务。

    相关文章

      网友评论

          本文标题:CountDownLatch

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