zoukankan      html  css  js  c++  java
  • 单个线程等待:多个线程(任务)完成后,进行汇总合并

    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

  • 相关阅读:
    vue---思维导图
    vscode----vue中HTML代码tab键自动补全
    css选择器---继承,优先级,层叠
    前端性能优化---减少http请求数量和减少请求资源的大小
    浏览器的一个请求从发送到返回都经历了什么?
    【FAQ】maven包引入版本引发的问题
    【spring】Spring Boot:定制自己的starter
    【redis基础】
    【spring】SpringBoot之Servlet、Filter、Listener配置
    【spring cloud】服务启动后正常,但是无法上线,一直处于down状态
  • 原文地址:https://www.cnblogs.com/wsycoo/p/14515960.html
Copyright © 2011-2022 走看看