• 使用CompletableFuture多线程异步任务优化查询接口性能


    一、需求:文书报告接口信息内容过多,涉及几十张表,十多个接口 由于积木报表是串行执行接口响应时间过长需要优化,而各个接口之间无顺序要求
    1、创建异步任务
    (1)supplyAsync介绍
    supplyAsync是创建带有返回值的异步任务

      //带返回值的异步请求,默认线程池
      public static  CompletableFuture supplyAsync(Supplier supplier) {
        return asyncSupplyStage(asyncPool, supplier);
    }
    //带返回值的异步请求,自定义线程池
    public static  CompletableFuture supplyAsync(Supplier supplier,  Executor executor) {
        return asyncSupplyStage(screenExecutor(executor), supplier);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    (2)示例如下:不同任务之间没有顺序关系的任务

      CompletableFuture<List<Order>> future1 = CompletableFuture.supplyAsync(() -> findOrder(id));
      CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> getStr(id));
      CompletableFuture<Map<String,Object>> future3 = CompletableFuture.supplyAsync(() -> getMap(id));
      CompletableFuture<Integer> future4 = CompletableFuture.supplyAsync(() -> getInte(id));
           
    
    • 1
    • 2
    • 3
    • 4
    • 5

    2、等待所有任务完成,获取结果然后封装返回
    (1)allOf介绍

    	CompletableFuture中多个任务都执行完成后才会执行,
    	只有有一个任务执行异常,则返回的CompletableFuture执行get方法时会抛出异常,
    	如果都是正常执行,则get返回null
    
    • 1
    • 2
    • 3

    (2)示例如下:

    CompletableFuture<Void> allFutures = CompletableFuture.allOf(future1,future2,future3,future4);
     try {
                allFutures.get();   // 等待所有任务完成
                List<Order> result1 = future1.join(); // 获取第一个任务的结果
                String result2 = future2.join();
                Map<String,Object> result3=future3.join();
                Integer result4  =future4.join();
                String finalResult = result1 + " " + result2+ " " + result3+ " " + result4;
                System.out.println("最后封装结果: " + finalResult);
            } catch (InterruptedException | ExecutionException e) {
                e.printStackTrace();
            }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    3、测试代码(完整版)如下

    public class CompletableFutureTest {
    
        public static void main(String[] args) {
            String id="xxx";
            CompletableFuture<List<Order>> future1 = CompletableFuture.supplyAsync(() -> findOrder(id));
            CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> getStr(id));
            CompletableFuture<Map<String,Object>> future3 = CompletableFuture.supplyAsync(() -> getMap(id));
            CompletableFuture<Integer> future4 = CompletableFuture.supplyAsync(() -> getInte(id));
            CompletableFuture<Void> allFutures = CompletableFuture.allOf(future1,future2,future3,future4);
            try {
                allFutures.get();   // 等待所有任务完成
                List<Order> result1 = future1.join(); // 获取第一个任务的结果
                String result2 = future2.join();
                Map<String,Object> result3=future3.join();
                Integer result4  =future4.join();
                String finalResult = result1 + " " + result2+ " " + result3+ " " + result4;
                System.out.println("Final Result: " + finalResult);
            } catch (InterruptedException | ExecutionException e) {
                e.printStackTrace();
            }
    
        }
        public static List<Order> findOrder(String id){
            System.out.println("执行future1:findOrder方法----------------");
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return new ArrayList<>();
        }
        public static String getStr(String id){
            System.out.println("执行future2:getStr----------------");
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return "new ArrayList<>()";
        }
        public static Map<String,Object> getMap(String id){
            System.out.println("执行future3:getMap----------------");
            return null;
        }
        public static Integer getInte(String id){
            System.out.println("执行future4:getInte----------------");
            return null;
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50

    4、总结
    在这个示例中,使用了 CompletableFuture.supplyAsync() 方法创建4个返回值不同的 CompletableFuture,分别从不同的方法中获取数据。然后,使用 CompletableFuture.allOf()allFutures.get()方法等待所有 CompletableFuture 完成并确认是否有方法异常。之后,通过调用 CompletableFuture.join() 方法来获取各个 CompletableFuture 的结果,并进行结果的组装。

    需要注意的是,allFutures.get() 是一个阻塞调用,将等待所有 CompletableFuture 完成。所以要确保在调用 get() 方法之前已经创建了所有的 CompletableFuture。

  • 相关阅读:
    求2个字符串的最短编辑距离 java 实现
    数据结构:二叉树的顺序结构--堆
    【LeetCode】移除盒子 [H](记忆化搜索)
    mysql 索引
    CSDN: ABTest流量分层分桶机制
    Unity 开发人员转CGE(castle Game engine)城堡游戏引擎指导手册
    数据中心的能耗焦虑, 到底有没有最优解?
    Protobuf 和 Thrift对比(转)
    [附源码]Python计算机毕业设计Django校园一卡通服务平台
    c++参数传递
  • 原文地址:https://blog.csdn.net/yuchenai/article/details/134006381