CountDownLatch

作者: 淡季的风 | 来源:发表于2020-08-09 23:34 被阅读0次

    CountDownLatch

    CountDownLatch是一个同步器, 允许一个或多个线程执行完毕,再继续执行, 可以用来协调多个线程的同步。
    CountDownLatch通过计数器实现, 计数器的初始值是线程的数量, 每当一个线程执行完毕, 计数器减1, 当计数器减为0或达到超时时间时, 等待的线程开始恢复执行。

    应用场景

    • 某一个线程等待n个线程执行完毕, CountDownLatch初始化为CountDownLatch(n), 当某个任务线程执行执行结束时,调用countDown方法,计数器减1, 当计数器减为0时, 表示n个任务线程全部执行完毕,await的线程被唤醒, 开始执行。典型场景为,主线程等待所有子任务结束,继续下一步。 比如服务启动时等待多个组件加载完毕,启动服务。

    • 多个线程等待某个线程执行结束, 开始并发执行, CountDownLatch初始化为CountDownLatch(1), 每个等待线程启动时调用该CountDownLatch await方法被阻塞, 当主线程执行完成, 计数器减1, 同时唤醒多个等待线程开始执行。

    重要方法

        // 构造器
        public CountDownLatch(int count) {}
        //
        public void await() throws InterruptedException {}
        //
        public boolean await(long timeout, TimeUnit unit) throws InterruptedException{}
        //
        public void countDown() {}
    
    • 构造器
      CountDownLatch的构造器仅有一个int参数, 代表阻塞的线程数量。
    • await
      调用此方法的线程会被挂起, 直到count值降为0才会被唤醒。
    • await(long timeout, TimeUnit unit)
      调用此方法的线程会被挂起, 直到count值降为0或超时才会被唤醒。
    • countDown
      调用此方法, count值减1

    示例

    • 主线程等待n个线程执行结束
            final CountDownLatch countDownLatch = new CountDownLatch(10);
            for(int i=0; i<10; i++){
                final int finalI = i;
                Runnable thread = new Runnable() {
                    @Override
                    public void run() {
                        System.out.println(finalI);
                        countDownLatch.countDown();
                    }
                };
                thread.run();
            }
            countDownLatch.await();
    
    • 并发执行
            ExecutorService service = Executors.newCachedThreadPool();
            final CountDownLatch countDownLatch = new CountDownLatch(1);
            final CountDownLatch countDownLatch1 = new CountDownLatch(10);
            final int[] a = {0};
            for(int i=0; i<10; i++){
                Runnable thread = new Runnable() {
                    @Override
                    public void run() {
                        try {
                            System.out.println(a[0]);
                            countDownLatch.await();
                            a[0] += 1;
                            countDownLatch1.countDown();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                };
                service.execute(thread);
            }
            countDownLatch.countDown();
            countDownLatch1.await();
            System.out.println(a[0]);
    

    原理解析

    TODO AQS

    相关文章

      网友评论

        本文标题:CountDownLatch

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