使用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);
}

(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));
       

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

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

(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();
        }

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;
    }
}

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

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

你可能感兴趣的:(java,1024程序员节)