CompletableFuture
Since JDK1.8
Author: Doug Lea
类说明
CompletableFuture可以显式完成的Future(设置其值和状态),可以用作CompletionStage,支持在其完成时触发的依赖函数和操作。
当两个或多个线程尝试完成、completeexception或取消一个CompletableFuture时,只有一个线程成功。
除了这些和直接操作状态和结果的相关方法之外,CompletableFuture用以下策略实现了接口CompletionStage:
- 为非异步方法的依赖完成提供的操作可以由完成当前CompletableFuture的线程执行,也可以由完成方法的任何其他调用者执行。
- 所有没有显式Executor参数的异步方法都使用ForkJoinPool.commonPool()执行(除非它不支持至少两个并行级别,在这种情况下,创建一个新线程来运行每个任务)。为了简化监视、调试和跟踪,所有生成的异步任务都是标记接口CompletableFuture.AsynchronousCompletionTask的实例。
- 所有CompletionStage方法的实现都独立于其他公共方法,因此一个方法的行为不受子类中其他方法的覆盖的影响。
CompletableFuture还通过以下策略实现Future:
- 由于(与FutureTask不同)该类对导致其完成的计算没有直接控制,因此取消被视为另一种形式的异常完成。方法cancel与completeexception (new CancellationException())具有相同的效果。方法iscompletedexception可用于确定CompletableFuture是否以任何异常方式完成。
- 在使用CompletionException异常完成的情况下,方法get()和get(long, TimeUnit)抛出一个ExecutionException,其原因与对应的CompletionException中持有的原因相同。为了简化大多数上下文中的使用,这个类还定义了join()和getNow方法,在这些情况下直接抛出CompletionException。
成功失败回调处理
下面是一个轮询处理任务,需要对成功和失败分别作出结果回写。 `
@Slf4j
@Service
@RequiredArgsConstructor
public class PullBombDataService {
private final NotifySyncBombStatusService notifySyncBombStatusService;
private final SyncBombDataService syncBombDataService;
@Value("${service.config.scheduleEnabled:true}")
public Boolean scheduleEnabled;
@Scheduled(cron = "0/30 * * * * ?")
public void pull() {
PullingDataTypeParameter parameter = notifySyncBombStatusService.getNodeRegisterService().getNodeParameter();
SeparateRestService restService = notifySyncBombStatusService.getNodeRegisterService().selectOauthService();
SyncBombContractOrder syncBombContractOrder = restService.pollingBombCompletedOrderToFactory(parameter);
if (null != syncBombContractOrder) {
CompletableFuture.supplyAsync(() -> {
try {
log.info("开始同步数据........");
syncBombDataService.syncData(syncBombContractOrder);
log.info("开始同步数据......完成");
return 1;
} catch (Exception e) {
e.printStackTrace();
throw e;
}
}).handle((result,e)->{
if(null != e){
log.error("同步数据异常......通知更新数据错误信息....");
StringBuilder sb = new StringBuilder(e.getCause().getMessage());
sb.append(e.getMessage());
notifySyncBombStatusService.notifySyncBombStatusInfo(syncBombContractOrder,sb.toString());
}else{
log.info("同步数据成功......通知更新数据成功信息....");
notifySyncBombStatusService.notifySyncBombStatusInfo(syncBombContractOrder,"");
}
return result;
});
} else {
log.warn("{}轮询消费BOMB数据同步,暂无需要处理的数据!!!", parameter.getDestination());
}
}
}
`
上面的业务本身有多套实现,而每个数据同步只需要关心自己同步逻辑,最终成功通知进行统一处理。
同步只干自己的业务
不同客户端对数据的处理
同步效果图: