了解Java中Future演进历史的同学应该知道,Dubbo 2.6.x及之前版本中使用的Future是在java 5中引入的,所以存在以上一些功能设计上的问题,而在java 8中引入的CompletableFuture进一步丰富了Future接口,很好的解决了这些问题。
Dubbo在2.7.0版本已经升级了对Java 8的支持,同时基于CompletableFuture对当前的异步功能进行了增强。
CompletableFuture 实例
- 创建一个CompletableFuture列表,每个CompletableFuture对象代表一个异步调用的结果
- CompletableFuture对象定义了执行完成后的操作及异常处理
- 使用CompletableFuture.allOf()方法将这个CompletableFuture列表组合成一个新的CompletableFuture对象
- join()方法会阻塞当前线程,直到对应的异步调用完成并返回结果
List<Point> resultList = Lists.newCopyOnWriteArrayList();
CompletableFuture.allOf(Lists.partition(uidList, limit).stream().map(subUidList -> {return pointClient.batchGetPoint(new BatchPointReq(subUidList)).whenComplete((res, thr) -> {if (thr != null) {logger.warn("batchGetPoint fail, req: {}", req, thr);} else if (res.isSuccess()) {resultList.addAll(res.getPointList());}});
}).toArray(CompletableFuture[]::new)).join();
// 亦可在总CompletableFuture使用`thenApply()`合并结果
return resultList;
非Dubbo接口的异步化 CompletableFuture.supplyAsync(() -> pointClient.batchGetPoint(new BatchPointReq(subUidList)), threadPool)
参考资料:
- Dubbo异步化实践
- 如何基于Dubbo实现全异步调用链
- Java 并发编程 Future及CompletionService
- 20个使用 Java CompletableFuture的例子