CompletableFuture

200 阅读8分钟

1、Future

Future:是 Java 并发编程中的一部分,它代表了异步计算的结果。当你提交一个任务给 ExecutorService 执行时,它会返回一个 Future 对象,这个对象可以用来检查计算是否完成,等待计算的结果,或者取消任务。

以下是 Future 的常用方法:

public interface Future<V> {

    /**
     * 尝试取消任务,如果任务尚未开始,那么它将不会执行,如果任务已经开始,那么这个参数决定是否应该中断正在运行的任务。
     */
    boolean cancel(boolean mayInterruptIfRunning);

    /**
     * 判断任务是否取消,若取消,则返回 true,否则返回 false。
     */
    boolean isCancelled();

    /**
     * 判断任务是否完成,若完成,则返回 true,否则返回 false。
     */
    boolean isDone();

    /**
     * 等待计算完成并获取计算的结果,如果计算尚未完成,则此方法会阻塞调用线程,直到计算完成。
     */
    V get() throws InterruptedException, ExecutionException;

    /**
     * 等待计算完成并获取计算的结果,如果计算尚未完成,则此方法会阻塞调用线程,直到计算完成或阻塞时间达到 timeout。
     */
    V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException;
}

2、函数式接口

函数式接口输入输出
Function<T, R>一个类型为T的对象一个类型为R的结果
Consumer一个类型为T的对象无(void)
Supplier一个类型为T的对象一个布尔值(true或false)
Predicate一个类型为T的对象
UnaryOperator一个类型为T的对象一个类型为T的结果
BinaryOperator两个类型为T的对象一个类型为T的结果
BiFunction<T, U, R>一个类型为T的对象和一个类型为U的对象一个类型为R的结果
BiConsumer<T, U>一个类型为T的对象和一个类型为U的对象无(void)
Runnable无(void)
Callable一个类型为T的结果

3、CompletableFuture

CompletableFuture:是Java 8 引入的一个类,它提供了一个可编程的、异步的、非阻塞的、易于使用的异步编程模型。

CompletableFuture 类实现了 CompletionStage 接口和 Future 接口。

  • CompletionStage:用于表示异步计算中的一个阶段,它可以是异步操作的结果,也可以是异步操作的开始。
  • Future:定义了基本的异步操作和结果获取方法。

CompletableFuture 和 Future 的对比:

  • 功能:CompletableFutureFuture 的基础上提供了更丰富的功能,包括非阻塞获取结果、支持流式调用、支持异常处理、支持回调等。
  • 使用方式:Future 通常与 ExecutorService 一起使用,用于提交异步任务并获取结果。CompletableFuture 可以独立使用,也可以与 ExecutorService 一起使用,提供了更多灵活的异步编程方式。
  • 链式调用:Future 不支持链式调用、CompletableFuture 支持链式调用。
  • 异常处理:Future 需要手动捕获和处理异步操作的异常、CompletableFuture 提供了 exceptionally 方法,可以方便地处理异步操作中的异常。

3.1 基础方法

get()

  • 阻塞当前线程,直到 CompletableFuture 完成,并返回计算的结果。

get(long timeout, TimeUnit unit)

  • 阻塞当前线程,直到 CompletableFuture 完成或达到指定的超时时间,然后返回计算的结果。

getNow(T valueIfAbsent)

  • 如果 CompletableFuture 已经完成,则返回其结果,如果尚未完成,则返回提供的 valueIfAbsent 值。

complete(T value)

  • 如果 CompletableFuture 尚未完成,使用提供的值完成它。如果已经完成,则此方法没有效果。

cancel(boolean mayInterruptIfRunning)

  • 尝试取消 CompletableFuture 的执行。如果操作尚未启动,并且 mayInterruptIfRunning 为 true,则可以中断执行线程。

3.2 启动方法

supplyAsync(Supplier<U> supplier)

  • 使用 ForkJoinPool.commonPool() 作为线程池,异步地执行 Supplier 函数,返回一个 CompletableFuture 类型的对象。

supplyAsync(Supplier<U> supplier, Executor executor)

  • 使用指定的 Executor 作为线程池,异步地执行 Supplier 函数,返回一个 CompletableFuture<U> 类型的对象。

runAsync(Runnable runnable)

  • 使用 ForkJoinPool.commonPool() 作为线程池,异步地执行 Runnable 函数,返回一个 CompletableFuture 类型的对象。

runAsync(Runnable runnable, Executor executor)

  • 使用指定的 Executor 作为线程池,异步地执行 Runnable 函数,返回一个 CompletableFuture 类型的对象。

3.3 后续方法

thenApply(Function<? super T, ? extends U> fn)

  • 使用 ForkJoinPool.commonPool() 作为默认的线程池,当异步操作完成时,同步地执行提供的 Function 函数来转换结果,并返回一个新的 CompletableFuture。

thenApplyAsync(Function<? super T, ? extends U> fn)

  • 使用 ForkJoinPool.commonPool() 作为默认的线程池,当异步操作完成时,异步地应用提供的 Function 函数转换结果,并返回一个新的 CompletableFuture。

thenApplyAsync(Function<? super T, ? extends U> fn, Executor executor)

  • 使用指定的 Executor 作为线程池,当异步操作完成时,异步地应用提供的 Function 函数转换结果,并返回一个新的 CompletableFuture。

thenAccept(Consumer<? super T> action)

  • 使用 ForkJoinPool.commonPool() 作为默认的线程池,当异步操作完成时,同步地执行提供的 Consumer 函数来消费结果(有返回值),并返回一个新的 CompletableFuture。

thenAcceptAsync(Consumer<? super T> action)

  • 使用 ForkJoinPool.commonPool() 作为默认的线程池,当异步操作完成时,异步地执行提供的 Consumer 函数来消费结果(有返回值),并返回一个新的 CompletableFuture<U>

thenAcceptAsync(Consumer<? super T> action, Executor executor)

  • 使用指定的 Executor 作为线程池,当异步操作完成时,异步地应用提供的 Consumer 函数消费结果(有返回值),并返回一个新的 CompletableFuture。

thenRun(Runable action)

  • 使用 ForkJoinPool.commonPool() 作为默认的线程池,当异步操作完成时,同步地执行提供的 Runnable 函数来消费结果(无返回值),并返回一个新的 CompletableFuture。

thenRunAsync(Runable action)

  • 使用 ForkJoinPool.commonPool() 作为默认的线程池,当异步操作完成时,异步地执行提供的 Runnable 函数来合并结果(无返回值),并返回一个新的 CompletableFuture。

thenRunAsync(Runable action, Executor executor)

  • 使用指定的 Executor 作为线程池,当异步操作完成时,当异步操作完成时,异步地执行提供的 Runnable 函数来合并结果(无返回值),并返回一个新的 CompletableFuture。

thenCombine(CompletionStage<? extends U> other, BiFunction<? super T,? super U,? extends V> fn)

  • 使用 ForkJoinPool.commonPool() 作为线程池,当异步操作完成时,同步地执行提供的 BiFunction 函数来合并结果,并返回一个新的 CompletableFuture。

thenCombineAsync(CompletionStage<? extends U> other, BiFunction<? super T,? super U,? extends V> fn)

  • 使用 ForkJoinPool.commonPool() 作为线程池,当异步操作完成时,异步地执行提供的 BiFunction 函数来合并结果,并返回一个新的 CompletableFuture。

thenCombineAsync(CompletionStage<? extends U> other, BiFunction<? super T,? super U,? extends V> fn, Executor executor)

  • 使用指定的 Executor 作为线程池,异步地执行提供的 BiFunction 函数来合并结果,并返回一个新的 CompletableFuture<U>,并返回一个新的 CompletableFuture。

thenAcceptBoth(CompletionStage<? extends U> other, BiConsumer<? super T, ? super U> action)

  • 使用 ForkJoinPool.commonPool() 作为线程池,当前 CompletableFuture 和 other 都完成后,同步地应用提供的 BiConsumer 函数处理结果,并返回一个新的 CompletableFuture。

thenAcceptBothAsync(CompletionStage<? extends U> other, BiConsumer<? super T, ? super U> action)

  • 使用 ForkJoinPool.commonPool() 作为线程池,当前 CompletableFuture 和 other 都完成后,异步地应用提供的 BiConsumer 函数处理结果,,并返回一个新的 CompletableFuture。

thenAcceptBothAsync(CompletionStage<? extends U> other, BiConsumer<? super T, ? super U> action, Executor executor)

  • 使用指定的 Executor 作为线程池,当前 CompletableFuture 和 other 都完成后,异步地应用提供的 BiConsumer 函数处理结果,,并返回一个新的 CompletableFuture。

3.4 依赖组合方法

runAfterBoth(CompletionStage<?> other, Runnable action)

  • 使用 ForkJoinPool.commonPool() 作为线程池,当前 CompletableFuture 和 other 都完成后,同步地执行一个 Runnable 操作,并返回一个新的 CompletableFuture。

runAfterBothAsync(CompletionStage<?> other, Runnable action)

  • 使用 ForkJoinPool.commonPool() 作为线程池,当前 CompletableFuture 和 other 都完成后,异步地执行一个 Runnable 操作,并返回一个新的 CompletableFuture。

runAfterBothAsync(CompletionStage<?> other, Runnable action, Executor executor)

  • 使用指定的 Executor 作为线程池,当前 CompletableFuture 和 other 都完成后,异步地执行一个 Runnable 操作,并返回一个新的 CompletableFuture。

runAfterEither(CompletionStage<?> other, Runnable action)

  • 使用 ForkJoinPool.commonPool() 作为线程池,当前 CompletableFuture 和 other 中的任意一个完成后,同步地执行一个 Runnable 操作,并返回一个新的 CompletableFuture<U>

runAfterEitherAsync(CompletionStage<?> other, Runnable action)

  • 使用 ForkJoinPool.commonPool() 作为线程池,当前 CompletableFuture 和 other 中的任意一个完成后,异步地执行一个 Runnable 操作,并返回一个新的 CompletableFuture。

runAfterEitherAsync(CompletionStage<?> other, Runnable action, Executor executor)

  • 使用指定的 Executor 作为线程池,当前 CompletableFuture 和 other 中的任意一个完成后,异步地执行一个 Runnable 操作,并返回一个新的 CompletableFuture。

3.5 组合完成方法

allOf(CompletableFuture<?>... cfs)

  • 等待所有提供的 CompletableFuture 实例完成。

anyOf(CompletableFuture<?>... cfs)

  • 等待任意一个提供的 CompletableFuture 实例完成。

3.6 完成处理方法

whenComplete(BiConsumer<? super T, ? super Throwable> action)

  • 使用 ForkJoinPool.commonPool() 作为线程池,在 CompletableFuture 完成后,无论成功还是失败,都执行一个操作。

whenCompleteAsync(BiConsumer<? super T, ? super Throwable> action)

  • 使用 ForkJoinPool.commonPool() 作为线程池,异步地在 CompletableFuture 完成后,无论成功还是失败,都执行一个操作。

whenCompleteAsync(BiConsumer<? super T, ? super Throwable> action, Executor executor)

  • 使用指定的 Executor 作为线程池,异步地在 CompletableFuture 完成后,无论成功还是失败,都执行一个操作。

3.7 异常处理方法

exceptionally(Function<Throwable, ? extends T> fn)

  • 使用 ForkJoinPool.commonPool() 作为线程池,当 CompletableFuture 执行过程中发生异常时,同步使用提供的 Function 函数来生成一个替代的结果。

exceptionallyAsync(Function<Throwable, ? extends T> fn)

  • 使用 ForkJoinPool.commonPool() 作为线程池,当 CompletableFuture 执行过程中发生异常时,异步使用提供的 Function 函数来生成一个替代的结果。

exceptionallyAsync(Function<Throwable, ? extends T> fn, Executor executor)

  • 使用指定的 Executor 作为线程池,当 CompletableFuture 执行过程中发生异常时,异步使用提供的 Function 函数来生成一个替代的结果。

3.8 异常链式处理方法

exceptionallyCompose(Function<Throwable, ? extends CompletionStage<T>> fn)

  • 使用 ForkJoinPool.commonPool() 作为线程池,当 CompletableFuture 执行过程中发生异常时,同步使用提供的 Function 函数创建一个新的 CompletionStage。

exceptionallyComposeAsync(Function<Throwable, ? extends CompletionStage<T>> fn)

  • 使用 ForkJoinPool.commonPool() 作为线程池,当 CompletableFuture 执行过程中发生异常时,异步使用提供的 Function 函数创建一个新的 CompletionStage。

exceptionallyComposeAsync(Function<Throwable, ? extends CompletionStage<T>> fn, Executor executor)

  • 使用指定的 Executor 作为线程池,当 CompletableFuture 执行过程中发生异常时,异步使用提供的 Function 函数创建一个新的 CompletionStage。