@[toc]
Java CompletableFuture
一、CompletableFuture 介绍
CompletableFuture 是 Java 8 中引入的一个新特性,它提供了一种简单的方法来实现异步编程和任务组合。
二、重点方法
1、 创建任务方法
- 有返回值:
supplyAsync(Supplier<U> supplier)supplyAsync(Supplier<U> supplier, Executor executor)
- 无返回值
runAsync(Runnable runnable)runAsync(Runnable runnable, Executor executor)
2、结果处理类
-
处理结果,返回新值
thenApply(Function<? super T,? extends U> fn);thenApplyAsync(Function<? super T,? extends U> fn);thenApplyAsync(Function<? super T,? extends U> fn, Executor executor);
-
消费结果,但不返回值
thenAccept(Consumer<? super T> action);thenAcceptAsync(Consumer<? super T> action);thenAcceptAsync(Consumer<? super T> action, Executor executor);
-
无参,无返回值
thenRun(Runnable action);thenRunAsync(Runnable action);thenRunAsync(Runnable action, Executor executor);
-
处理结果,实现扁平化嵌套
thenCompose (Function<? super T, ? extends CompletionStage<U>> fn);thenComposeAsync (Function<? super T, ? extends CompletionStage<U>> fn);thenComposeAsync (Function<? super T, ? extends CompletionStage<U>> fn, Executor executor);
3、任务组合类
-
两个任务执行完,再执行第三个任务,处理结果,也有返回。T+U→R
thenCombine (CompletionStage<? extends U> other, BiFunction<? super T,? super U,? extends V> fn);thenCombineAsync (CompletionStage<? extends U> other, BiFunction<? super T,? super U,? extends V> fn);thenCombineAsync (CompletionStage<? extends U> other, BiFunction<? super T,? super U,? extends V> fn, Executor executor);
-
两个任务执行完,再执行第三个任务,处理结果,没有返回
-
thenAcceptBoth(CompletionStage<? extends U> other, BiConsumer<? super T, ? super U> action); thenAcceptBothAsync(CompletionStage<? extends U> other, BiConsumer<? super T, ? super U> action); thenAcceptBothAsync(CompletionStage<? extends U> other, BiConsumer<? super T, ? super U> action, Executor executor);
-
-
两个任务执行完,再执行第三个,不处理结果,也没有返回
-
runAfterBoth(CompletionStage<?> other, Runnable action); runAfterBothAsync(CompletionStage<?> other, Runnable action); runAfterBothAsync(CompletionStage<?> other, Runnable action, Executor executor);
-
-
两个任务只要有一个完成,就执行任务三,不处理结果,也没返回值
-
runAfterEither(CompletionStage<?> other, Runnable action); runAfterEitherAsync(CompletionStage<?> other, Runnable action); runAfterEitherAsync(CompletionStage<?> other, Runnable action, Executor executor);
-
-
两个任务只要有一个完成,就执行任务三,处理结果,没有返回值
-
acceptEither(CompletionStage<? extends T> other, Consumer<? super T> action); acceptEitherAsync(CompletionStage<? extends T> other, Consumer<? super T> action); acceptEitherAsync(CompletionStage<? extends T> other, Consumer<? super T> action, Executor executor);
-
-
两个任务只要有一个完成,就执行任务三,处理结果,有返回值
-
applyToEither(CompletionStage<? extends T> other, Function<? super T, U> fn); applyToEitherAsync(CompletionStage<? extends T> other, Function<? super T, U> fn); applyToEitherAsync(CompletionStage<? extends T> other, Function<? super T, U> fn, Executor executor);
-
-
所有任务完成,适用于并行任务聚合
allOf(CompletableFuture<?>... cfs)
-
任一任务完成,就返回结果,适用于竞争场景
anyOf(CompletableFuture<?>... cfs)
4、异常处理类
-
处理异常结果,有返回值
exceptionally(Function<Throwable, ? extends T> fn);
-
处理正常和异常结果,也有返回值
handle(BiFunction<? super T, Throwable, ? extends U> fn);
-
处理正常和异常结果,没有返回
-
whenComplete(BiConsumer<? super T, ? super Throwable> action); whenCompleteAsync(BiConsumer<? super T, ? super Throwable> action); whenCompleteAsync(BiConsumer<? super T, ? super Throwable> action, Executor executor);
-
三、如何对多线程进行编排
四、在 Java 中,如何实现高效的异步编程?如何避免回调地狱?
- 多个任务进行链式调用
- 使用
thenCombine()、allOf()、 anyOf()等方法,并行与组合执行
- 使用
exceptionally()或handle()方法处理异常
- 链式操作,避免回调地狱
- 使用
whenComplete或handle处理任务结果和异常
- 使用
allOf()和anyOf()合并多个任务
- 使用 ExecutorService 配合 CompletableFuture进行并发执行
五、如何实现主线程捕获子线程异常
参考:Java 八股/03-Java 并发/为什么不能在try-catch中捕获子线程的异常?.md
你可以使用 CompletableFuture.supplyAsync() 来执行任务,并使用handle()方法捕获异常