一、需求:文书报告接口信息内容过多,涉及几十张表,十多个接口 由于积木报表是串行执行接口响应时间过长需要优化,而各个接口之间无顺序要求
1、创建异步任务
(1)supplyAsync介绍
supplyAsync是创建带有返回值的异步任务
//带返回值的异步请求,默认线程池
public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier) {
return asyncSupplyStage(asyncPool, supplier);
}
//带返回值的异步请求,自定义线程池
public static <U> CompletableFuture<U> supplyAsync(Supplier<U> 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。