计算结果完成时的回调方法
当 CompletableFuture 的计算结果完成,或者抛出异常的时候,可以执行特定的 Action。主要是下面的方法:
public CompletableFuture<T> whenComplete(BiConsumer<? super T,? super Throwable> action)
public CompletableFuture<T> whenCompleteAsync(BiConsumer<? super T,? super Throwable> action)
public CompletableFuture<T> whenCompleteAsync(BiConsumer<? super T,? super Throwable> action, Executor executor)
public CompletableFuture<T> exceptionally(Function<Throwable,? extends T> fn)
可以看到 Action 的类型是 BiConsumer<? super T,? super Throwable>它可以处理正常的计算结果,或者异常情况。
whenComplete 和 whenCompleteAsync 的区别:
-
whenComplete:是执行当前任务的线程执行继续执行 whenComplete 的任务。
-
whenCompleteAsync:是执行把 whenCompleteAsync 这个任务继续提交给线程池来进行执行。
示例代码
public static void whenComplete() throws Exception {CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {try {TimeUnit.SECONDS.sleep(1);} catch (InterruptedException e) {}if(new Random().nextInt()%2>=0) {int i = 12/0;}System.out.println("run end ...");});future.whenComplete(new BiConsumer<Void, Throwable>() {@Overridepublic void accept(Void t, Throwable action) {System.out.println("执行完成!");}});future.exceptionally(new Function<Throwable, Void>() {@Overridepublic Void apply(Throwable t) {System.out.println("执行失败!"+t.getMessage());return null;}});TimeUnit.SECONDS.sleep(2);
}
handle 方法
handle 是执行任务完成时对结果的处理。handle 方法和 thenApply 方法处理方式基本一样。不同的是 handle 是在任务完成后再执行,还可以处理异常的任务。thenApply 只可以执行正常的任务,任务出现异常则不执行 thenApply 方法。
public <U> CompletionStage<U> handle(BiFunction<? super T, Throwable, ? extends U> fn);
public <U> CompletionStage<U> handleAsync(BiFunction<? super T, Throwable, ? extends U> fn);
public <U> CompletionStage<U> handleAsync(BiFunction<? super T, Throwable, ? extends U> fn,Executor executor);
示例代码
public static void handle() throws Exception{CompletableFuture<Integer> future = CompletableFuture.supplyAsync(new Supplier<Integer>() {@Overridepublic Integer get() {int i= 10/0;return new Random().nextInt(10);}}).handle(new BiFunction<Integer, Throwable, Integer>() {@Overridepublic Integer apply(Integer param, Throwable throwable) {int result = -1;if(throwable==null){result = param * 2;}else{System.out.println(throwable.getMessage());}return result;}});System.out.println(future.get());
}
从示例中可以看出,在 handle 中可以根据任务是否有异常来进行做相应的后续处理操作。而 thenApply 方法,如果上个任务出现错误,则不会执行 thenApply 方法。