• 单个线程等待:多个线程(任务)完成后,进行汇总合并


    public class TestCountDownLatch1 {
         public static void main(String[] args) throws InterruptedException {
              int count = 3;
              CountDownLatch countDownLatch = new CountDownLatch(count);
              for (int i = 0; i < count; i++) {
                   final int index = i;
                   new Thread(() -> {
                        try {
                             Thread.sleep(1000 + ThreadLocalRandom.current().nextInt(1000));
                             System.out.println("finish" + index + Thread.currentThread().getName());
                        } catch (InterruptedException e) {
                             e.printStackTrace();
                        }finally{
                            countDownLatch.countDown();
                        }
                   }).start();
              }
              countDownLatch.await();// 主线程在阻塞,当计数器==0,就唤醒主线程往下执行。
              System.out.println("主线程:在所有任务运行完成后,进行结果汇总");
         }
    }
    

      这种场景应该是用的最多了,比如我们打开一个电商的个人中心页面,我们需要调用,用户信息接口、用户订单接口、用户会员信息等接口,然后合并后一起给到前端,假设每个接口最长耗时为1s,如果我们同步调用的话最大耗时时间是3s,如果我们采用异步调用然后合并结果,所以最大的耗时时间是3s。每个接口调用返回数据后调用countDown方法,让计数器进行减1,当把计数器减为0时的这个线程会去唤醒主线程,让它继续往下走。

    个人理解:

     long start = System.currentTimeMillis();
            int count = 3;
            CountDownLatch countDownLatch = new CountDownLatch(count);
            for (int i = 0; i < count; i++) {
                final int index = i;
                int finalI = i;
                new Thread(() -> {
                    try {
    //                    Thread.sleep(1000 + ThreadLocalRandom.current().nextInt(1000));
                        if(0 == finalI){
                            T1();
                        }
                        if(1 == finalI){
                            T2();
                        }
                        if(2 == finalI){
                            T3();
                        }
                        System.out.println("finish" + index + Thread.currentThread().getName());
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }finally{
                        countDownLatch.countDown();
                    }
                }).start();
            }
            countDownLatch.await();// 主线程在阻塞,当计数器==0,就唤醒主线程往下执行。
            System.out.println("主线程:在所有任务运行完成后,进行结果汇总");
            System.out.println(System.currentTimeMillis()-start);
        }
    
        public void T1() throws InterruptedException {
            Thread.sleep(1000);
            System.out.println("T1");
        }
    
        public void T2() throws InterruptedException {
            Thread.sleep(1000);
            System.out.println("T2");
        }
    
        public void T3() throws InterruptedException {
            Thread.sleep(1000);
            System.out.println("T3");
        }
    

      执行结果

    地址https://mp.weixin.qq.com/s/ga3x8LYxDMgCzdfn6UUT_w

  • 相关阅读:
    【Jenkins】之自动化测试持续集成
    【shell】正则表达式
    【openwrt】systemctl详解
    STM32(三十九)RS485串口通信
    ucos(十)信号量优先级反转
    ucos(九)互斥锁和死锁
    【线程】pthread介绍
    git push发现本地 代码没有更新到最新版本,但是已经commit怎么办?
    reset按键和ipget按键在openwrt中的处理逻辑
    用openwrt编译工具链编译一个可执行文件
  • 原文地址:https://www.cnblogs.com/wsycoo/p/14515960.html
Copyright © 2020-2023  润新知