背景
我的项目中,有这样一个场景,我们要发起一个用户主动还款之后,需要把在途的扣款单全部暂停,但是因为用户选择还款单据可能比较多,而且暂停是调用外部资金打款系统的接口实现的,这个地方如果一条一条执行就很慢,但是如果起多线程执行的话,我就没办法知道他们每一个暂定的返回结果。
我想可以实现一个这样的功能:多线程去执行暂停动作,如果都成功了,那么就推进我的主动扣款后续流程,如果暂停有任何一个接口调用失败了,那么先不推进后续流程,等下次重试。
技术选型
为了实现这个功能,我了解到CompletableFuture,他是Java 8中引入的一个新特性,它提供了一种简单的方法来实现异步编程和任务组合。
他的多线程编排的能力刚好可以用在我这个场景中,而且他底层是基于ForkJoinPool实现的,所以他的性能也比较高效(也可以使用自定义线程池
),所以最终我选择了这个方案。
具体实现
java
// 异步暂停扣款
CompletableFuture<Void> allFutures = CompletableFuture.allOf(noticeDetails.stream()
.map(detail -> CompletableFuture.supplyAsync(() -> {
pause(detail);
return null;
})).toArray(CompletableFuture[]::new));
// 所有暂停扣款成功后,更新代还通知单
allFutures.whenComplete((v, e) -> {
if (e == null) {
// 执行后续的还款操作
// ...
// ...
} else {
log.error("notice failed", e);
}
});
得到结果
在用了CompletableFuture做编排之前,原来50笔订单的暂停扣款,需要大概10s左右,但是用了CompletableFuture之后,50笔订单的暂停扣款只需要1秒钟左右。