CompletableFuture的常见规则:
- 函数的执行方式一般有同步和异步两种,异步方式以
Async结尾、默认使用ForkJoinPool执行,也可以使用指定的executor。如:CompletableFuture.complete和CompletableFuture.completeAsyn - 被执行的函数一般有三种:应用函数applyXXX、消费函数acceptXXX、可执行函数runXXX。如:thenApply、thenAccept、thenRun,主要区别为是否接收参数及有无返回结果。
Function<? super T, U> fn:应用函数,接收前一阶段返回结果作为入参,有返回值
Consumer<? super T> action:消费函数:接收前一阶段返回结果作为入参,无返回值
Runnable action:执行函数:无入参,无返回值
- 静态方法创建CompletableFuture对象:
completedFuture:创建一个已经完成的 CompletableFuture 对象,其结果值为指定的值 value。
supplyAsync:创建一个异步执行的 CompletableFuture 对象,异步执行给定的供应者函数,返回计算结果。
runAsync:创建一个异步执行的 CompletableFuture 对象,异步执行给定的可运行任务,不返回结果。
completedStage:创建一个已经完成的阶段(stage) CompletableFuture 对象,其结果值为指定的值 value。
failedFuture:创建一个已经完成且异常的 CompletableFuture 对象,其结果为给定的异常 ex。
- 链式执行:
阻塞执行完前一个方法后才会执行后一个方法,如:
//执行顺序是f1->f2->f3,不论是异步执行还是同步执行的,都是将前一阶段的结果作为入参传入到下一个方法
CompletableFuture.completedFuture("message").thenApplyAsync(f1).thenApplyAsync(f2).thenApplyAsync(f3)
下列方法中,除了exceptionally外,都有对应的Asyn函数异步执行方法,exceptionally对应的异步异常处理可以用handleAsyn
thenApply:当异步操作执行成功时,用前一阶段的结果作为参数,接收一个处理函数,有返回结果
thenCompose:与thenApply类似,区别为thenApply的fn是对前一步的返回值进行处理,thenCompose的fn是对另一个CompletableFuture进行处理
thenAccept:当异步操作执行成功时,用前一阶段的结果作为参数,接收一个处理函数,不返回结果。
thenRun:当异步操作执行成功时,不接收参数,接收一个Runnable函数,不返回结果。
handle:无论操作是成功还是失败,用前一阶段的结果作为参数,接收一个处理函数,有返回结果。
whenComplete:无论操作是成功还是失败,用前一阶段的结果作为参数,接收一个处理函数,不返回结果。
exceptionally:当异步操作发生异常时,接收异常,接收一个处理函数,有返回结果。
- 手动完成CompletableFuture对象:
complete:手动将'未完成'的CompletableFuture对象变为完成状态,并设置它的结果值,返回手动执行的结果,它的依赖关系和后续操作仍然会按照正常的异步操作流程进行。
completeAsync:与 complete不同的是,completeAsync以异步的方式执行。
obtrudeValue:'强制'完成 CompletableFuture 对象,并设置一个成功的结果值。与 complete方法不同的是,obtrudeValue方法会立即完成 CompletableFuture 对象,而不考虑对象的状态。如果 CompletableFuture 对象已经完成或已经异常完成,obtrudeValue方法将强制替换结果值。该方法不会触发后续的回调函数或链式操作。
completeExceptionally:将异步操作标记为异常完成,并将指定的异常传递给后续的异常处理函数或链式操作
obtrudeException:强制完成 CompletableFuture 对象,并设置一个异常作为结果。与 completeExceptionally方法不同的是,obtrudeException方法会立即完成 CompletableFuture 对象,而不考虑对象的状态。如果 CompletableFuture 对象已经完成或已经异常完成,obtrudeException方法将强制替换异常结果。该方法不会触发后续的异常处理函数或链式操作。
cancel:尝试取消 CompletableFuture 对象的执行。如果取消成功,CompletableFuture 对象的状态将被标记为已取消,并且任何等待该对象完成的线程将接收到 CancellationException 异常
- 判断执行结果状态:
isCompletedNormally:用于检查 CompletableFuture 对象是否已经正常完成,即没有抛出异常
isDone:无论CompletableFuture 是正常完成、异常完成、还是被取消,只要任务结束了都返回true否则返回false
isCancelled:CompletableFuture是否被取消
isCompletedExceptionally:CompletableFuture是否异常完成
- 获取执行结果
join:阻塞当前线程获取返回结果值,如果任务执行异常时join方法会抛出异常,(用handle方法替换join方法使用)
get:阻塞当前线程获取返回结果值,可以设置等待时间
getNow:不阻塞立即获取结果值,如果有值了则返回,否则返回getNow传入的默认值
- 两个任务组合
applyToEither:两个CompletableFuture 中任意一个完成时,接收参数执行应用函数,有返回结果
acceptEither:两个CompletableFuture 中任意一个完成时,接收参数执行消费函数,无返回结果
thenCombine:两个CompletableFuture 都完成时,运行给定的方法,接收两个任务的结果作为入参,有返回结果
thenAcceptBoth:两个CompletableFuture 都完成时,运行给定的方法,接收两个任务的结果作为入参,无返回结果
runAfterBoth:两个CompletableFuture 都完成时,运行给定的方法,不接收参数,无返回结果
例子:
CompletableFuture<String> cf1 = CompletableFuture.supplyAsync(() -> {
//doSomething
return "1";
});
CompletableFuture<String> cf2 = CompletableFuture.supplyAsync(() -> {
//doSomething
return "2";
});
CompletableFuture<String> cf3 = cf1.applyToEither(cf2, Function.identity());
System.out.println(cf3.join());
说明:
Function.identity() 表示一个恒等函数,它接受一个参数并将其作为返回结果,cf1与cf2哪个先执行完则输出哪个任务的结果,在真实的场景中可以将Function.identity()改为自己的执行函数。
- 多个任务组合
allOf:用于条件与的汇总场景,生成新的CompletableFuture ,当所有任务都正常完成(无异常)时才算完成,没有返回结果,当任务集合中的某个任务异常时,其他的任务也会执行
anyOf:用于条件或场景,生成新的CompletableFuture ,只要有一个正常完成(无异常)就算完成,返回第一个完成的CompletableFuture结果值
例子:
public void testAllof(){
CompletableFuture<String> cf1 = CompletableFuture.supplyAsync(() -> {
timeCost(2000);
return "1";
});
CompletableFuture<String> cf2 = CompletableFuture.supplyAsync(() -> {
timeCost(1000);
throw new RuntimeException("");
});
CompletableFuture<String> cf3 = CompletableFuture.supplyAsync(() -> {
timeCost(3000);
return "3";
});
List<CompletableFuture<String>> cfList = Arrays.asList(cf1, cf2, cf3);
CompletableFuture[] arrs = cfList.toArray(CompletableFuture[]::new);
//需要用handle处理转换,防止cfList某个任务执行异常,不然使用join方法时会报错
CompletableFuture<String> allFuture = CompletableFuture.allOf(arrs).handle((v,ex)->{
if (ex != null) {
return "someone error";
}else{
return "all success";
}
});
//当cfList某个任务异常时,用join方法等待allOf生成的CompletableFuture会抛异常,所以用handle处理allOf生成新的CompletableFuture,同时任务集合的执行结果
CompletableFuture<List<String>> allOf = CompletableFuture.allOf(arrs).handle((v, th) -> {
//收集cfList结果
List<String> list = cfList.stream().map(i -> {
String tmp = i.handle((val, ex) -> {
return val;
}).join();
return tmp;
}).collect(Collectors.toList());
return list;
});
List<String> res = allOf.join();
System.out.println(res);