在一个业务代码中,一个接口中需要调用10个接口来获取必要的数据,数据放置于一个Map返回。
伪代码如下:
Map<String,Object> result = new HashMap<>();
method01(result,params01);
method02(result,params02);
method03(result,params03);
method04(result,params04);
method05(result,params05);
method06(result,params06);
method07(result,params07);
method08(result,params08);
method09(result,params09);
method10(result,params10);
return result;
假设method01~10分别耗时0.1、0.2、0.3、0.4、0.5、0.6、0.7、0.8、0.9、1.0,那么这个方法总耗时就是所有方法耗时之和:5.5
显然不可接受。
利用JDK提供的CompletableFuture进行异步编排所有的任务。
Map<String,Object> result = new ConcurrentHashMap<>();
CompletableFuture<Void> future01 = CompletableFuture.runAsync(() -> {
method01(result,params01);
});
CompletableFuture<Void> future02 = CompletableFuture.runAsync(() -> {
method02(result,params02);
});
CompletableFuture<Void> future03 = CompletableFuture.runAsync(() -> {
method03(result,params03);
});
CompletableFuture<Void> future04 = CompletableFuture.runAsync(() -> {
method04(result,params04);
});
CompletableFuture<Void> future05 = CompletableFuture.runAsync(() -> {
method05(result,params05);
});
CompletableFuture<Void> future06 = CompletableFuture.runAsync(() -> {
method06(result,params06);
});
CompletableFuture<Void> future07 = CompletableFuture.runAsync(() -> {
method07(result,params07);
});
CompletableFuture<Void> future08 = CompletableFuture.runAsync(() -> {
method08(result,params08);
});
CompletableFuture<Void> future09 = CompletableFuture.runAsync(() -> {
method09(result,params09);
});
CompletableFuture<Void> future10 = CompletableFuture.runAsync(() -> {
method10(result,params10);
});
CompletableFuture<Void> allOf = CompletableFuture.allOf(future01,future02,future03,future04,future05,future06,future07,future08,future09,future10);
try {
allOf.get();
} catch (Exception e) {
logger.error(e.getMessage(), e);
}
//用join来hold
//CompletableFuture.allOf(future01,future02,future03,future04,future05,future06,future07,future08,future09,future10).join();
return result;
这里通过将每个任务异步执行,通过allOf等待所有的任务执行完毕后返回,方法总耗时就粗略地等于最大的任务时间:1.0。极大地提高了效率。但是异步化后必须注意多线程安全问题,因为都会修改Map,所以要使用一个线程安全的Map(ConcurrentHashMap)
CompletableFuture还有更多好用的方法,参见如下文档:
https://my.oschina.net/JackieRiver/blog/2054472
https://www.jianshu.com/p/6f3ee90ab7d3
https://www.jianshu.com/p/80633d4f70e7