• 基础巩固篇 —— CountDownLatch的理解


    一、CountDownLatch是什么

    CountDownLatch是java.util.concurrent包下的类。它可以使线程处于等候状态,当任务执行数量递减为0时,自动唤醒等待线程。这样可以控制多线程的执行顺序。

    二、CountDownLatch的使用

        private Integer task1_sum = 0;
        private Integer task2_sum = 0;
        private Integer task3_sum = 0;
        private CountDownLatch countDownLatch = new CountDownLatch(2);
        // 第一个任务,从 1 加到 10
        public void task_1() {
            System.out.println("执行第一个任务");
            for (int i = 1; i < 10; i++) {
                task1_sum += i;
            }
            // countDownLatch递减,由 2 变为 1
            countDownLatch.countDown();
        }
        // 第二个任务,从 45 加到 55,执行时间超过3秒是为了与使用前对比
        public void task_2() throws InterruptedException {
            TimeUnit.SECONDS.sleep(3);
            System.out.println("执行第二个任务task1_sum为:" + task1_sum);
            Integer temp = task1_sum;
            for (int i = temp; i < temp + 10; i++) {
                task2_sum = task2_sum + i;
            }
            // countDownLatch递减,由 1 变为 0
            countDownLatch.countDown();
        }
        // 第三个任务,从 495 加到 505
        public void task_3() throws InterruptedException {
            // 执行到此,线程等待,等countDownLatch值递减为0,也就是其他任务已经完成后,自动唤醒执行后面的操作
            countDownLatch.await();
            System.out.println("执行第三个任务task2_sum为:" + task2_sum);
            Integer temp = task2_sum;
            for (int i = temp; i < temp + 10; i++) {
                task3_sum += i;
            }
        }
        // 先执行任务一和二,再执行任务三
        public void task_run() throws InterruptedException {
            this.task_1();
            new Thread(() -> {
                try {
                    this.task_2();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }, "aa").start();
            this.task_3();
        }
    
        public static void main(String[] args) throws InterruptedException {
            CountDownLatchDemo demo = new CountDownLatchDemo();
            demo.task_run();
        }
    

    使用CountDownLatch后执行顺序正确:

    执行第一个任务
    执行第二个任务task1_sum为:45
    执行第三个任务task2_sum为:495
    

    未使用CountDownLatch时,执行顺序错误:

    执行第一个任务
    执行第三个任务task2_sum为:0
    执行第二个任务task1_sum为:45
    

    一共有三个任务,因为任务二执行时间最长且异步,正常执行一定是先执行任务一三,最后执行完二。为了保证按顺序执行,可以使用CountDownLatch,初始设置任务数2,进入任务三线程进入等候状态,当任务二执行完任务数也递减为0,然后自动唤醒执行任务三线程。这样就控制了执行顺序。

    三、个人观点

    这种自动唤醒的方式,感觉跟阻塞队列类似。一看源码:

    /**
         * Synchronization control For CountDownLatch.
         * Uses AQS state to represent count.
         */
        private static final class Sync extends AbstractQueuedSynchronizer {
    

    其内部类Sync果然继承了AbstractQueuedSynchronizer队列抽象类。

  • 相关阅读:
    Cloudera Manager 4.6 安装部署hadoop CDH集群
    linux下统计目录下所有子目录的大小
    jvisualvm远程监控tomcat
    安装ubuntu server时可能会需要的配置
    安装配置maven私服-nexus
    maven环境配置
    各版本eclipse的maven配置
    转载:Centos7 从零编译Nginx+PHP+MySql 序言 一
    MongoDB系列一:CentOS7.2下安装mongoDB3.2.8
    MongoDB Windows环境安装及配置
  • 原文地址:https://www.cnblogs.com/zzb-yp/p/15045690.html
Copyright © 2020-2023  润新知