并发编程 CompletableFuture

本文将介绍并发编程中的 CompletableFuture 异步编程工具类。

一、什么是 CompletableFuture?

CompletableFuture 是 Java 在 1.8 版本中提供的对异步编程支持的工具类。

二、构造方法

1. runAsync()

  • CompletableFuture<Void> CompletableFuture.runAsync(Runnable runnable):返回一个 CompletableFuture 实例;实例中包含指定的 Runnable 任务,该任务会被公共的 ForkJoinPool 线程池执行
  • CompletableFuture<Void> CompletableFuture.runAsync(Runnable runnable, Executor executor):返回一个 CompletableFuture 实例;实例中包含指定的 Runnable 任务,该任务会指定的 Executor 执行器执行

2. supplyAsync()

Supplier 是一个函数式接口,表示调用后可以获取结果的方法。

1
2
3
4
5
6
@FunctionalInterface
public interface Supplier<T> {

T get();

}
  • CompletableFuture<U> CompletableFuture.supplyAsync(Supplier<U> supplier):返回一个 CompletableFuture 实例;实例中包含指定的 Supplier 任务,该任务会被公共的 ForkJoinPool 线程池执行;实例中包含任务执行后的返回值
  • CompletableFuture<U> CompletableFuture.supplyAsync(Supplier<U> supplier, Executor executor):返回一个 CompletableFuture 实例;实例中包含指定的 Supplier 任务,该任务会指定的 Executor 执行器执行;实例中包含任务执行后的返回值

三、任务何时运行?

CompletableFuture 实例一旦被创建,其任务便会自动异步执行。

四、结果如何获取?

CompletableFuture 实现了 Future 接口,可以用于查看运行状态、获取运行结果。

五、CompletionStage

1. 说明

CompletableFuture 实现了 CompletionStage 接口,该接口用于描述任务之间的时序关系(串行、并行、汇聚等)。

2. 描述串行

  • CompletionStage<R> thenApply(Function fn):同步;this 阶段结束后,接着执行 fn 的 apply() 方法,方法接收 this 阶段的结果为参数;返回的 CompletionStage 中包含的值为 fn 执行结果

    1
    ···.thenApply(num -> num + "Hello");
  • CompletionStage<R> thenApplyAsync(Function fn):异步;this 阶段结束后,接着执行 fn 的 apply() 方法,方法接收 this 阶段的结果为参数;返回的 CompletionStage 中包含的值为 fn 执行结果

  • CompletionStage<Void> thenAccept(Consumer consumer):同步;this 阶段结束后,接着执行 consumer 的 accept() 方法,方法接收 this 阶段的结果为参数

  • CompletionStage<Void> thenAcceptAsync(Function consumer):异步;this 阶段结束后,接着执行 consumer 的 accept() 方法,方法接收 this 阶段的结果为参数

  • CompletionStage<Void> thenRun(Runnable action):同步;this 阶段结束后,接着执行 action 的 run() 方法

  • CompletionStage<Void> thenRunAsync(Runnable action):异步;this 阶段结束后,接着执行 action 的 run() 方法

  • CompletionStage<R> thenCompose(Function fn):同步;this 阶段结束后,接着执行 fn 的 apply() 方法,该方法应该返回一个 CompletionStage,方法接收 this 阶段的结果为参数;返回的 CompletionStage 中包含的值为 fn 执行结果 CompletionStage 中包含的值

    1
    ···.thenApply(num -> CompletableFuture.supplyAsync(() -> num + "Hello");
  • CompletionStage<R> thenComposeAsync(Function fn):异步;this 阶段结束后,接着执行 fn 的 apply() 方法,该方法应该返回一个 CompletionStage,方法接收 this 阶段的结果为参数;返回的 CompletionStage 中包含的值为 fn 执行结果 CompletionStage 中包含的值

3. 描述 AND 汇聚

  • CompletionStage<R> thenCombine(CompletionStage other, BiFunction fn):同步;this 阶段与 other 阶段都结束后,接着执行 fn 的 apply() 方法,方法接收 this 阶段与 other 阶段的结果为参数;返回的 CompletionStage 中包含 fn 执行结果
  • CompletionStage<R> thenCombineAsync(CompletionStage other, BiFunction fn):异步;this 阶段与 other 阶段都结束后,接着执行 fn 的 apply() 方法,方法接收 this 阶段与 other 阶段的结果为参数;返回的 CompletionStage 中包含 fn 执行结果
  • CompletionStage<Void> thenAcceptBoth(CompletionStage other, BiConsumer consumer):同步;this 阶段与 other 阶段都结束后,接着执行 consumer 的 accept() 方法,方法接收 this 阶段与 other 阶段的结果为参数
  • CompletionStage<Void> thenAcceptBothAsync(CompletionStage other, BiConsumer consumer):异步;his 阶段与 other 阶段都结束后,接着执行 consumer 的 accept() 方法,方法接收 this 阶段与 other 阶段的结果为参数
  • CompletionStage<Void> runAfterBoth(CompletionStage other, Runnable action):同步;this 阶段与 other 阶段都结束后,接着执行 action 的 run() 方法
  • CompletionStage<Void> runAfterBothAsync(CompletionStage other, Runnable action):异步;this 阶段与 other 阶段都结束后,接着执行 action 的 run() 方法

4. 描述 OR 汇聚

  • CompletionStage applyToEither(CompletionStage other, Function fn):同步;一旦 this 阶段或 other 阶段结束,接着执行 fn 的 apply() 方法,方法接收结束阶段的结果为参数;返回的 CompletionStage 中包含 fn 执行结果
  • CompletionStage applyToEitherAsync(CompletionStage other, Function fn):异步;一旦 this 阶段或 other 阶段结束,接着执行 fn 的 apply() 方法,方法接收结束阶段的结果为参数;返回的 CompletionStage 中包含 fn 执行结果
  • CompletionStage acceptEither(CompletionStage other, Consumer consumer):同步;一旦 this 阶段或 other 阶段结束,接着执行 consumer 的 accept() 方法,方法接收结束阶段的结果为参数
  • CompletionStage acceptEitherAsync(CompletionStage other, Consumer consumer):异步;一旦 this 阶段或 other 阶段结束,接着执行 consumer 的 accept() 方法,方法接收结束阶段的结果为参数
  • CompletionStage runAfterEither(CompletionStage other, Runnable action):同步;一旦 this 阶段或 other 阶段结束,接着执行 action 的 run() 方法
  • CompletionStage runAfterEitherAsync(CompletionStage other, Runnable action):异步;一旦 this 阶段或 other 阶段结束,接着执行 action 的 run() 方法

5. 异常处理

  • CompletionStage exceptionally(Function fn):一旦 this 阶段发生异常,fn 的 apply() 方法将会被执行,方法接收异常为参数;返回的 CompletionStage 中包含的值为 fn 执行结果

  • CompletionStage whenComplete(BiConsumer consumer):同步;this 阶段结束后,接着执行 consumer 的 accept() 方法,方法接收 this 阶段的结果(如果没有则为 null)和异常(如果没有则为 null)为参数;返回的 CompletionStage 中包含的值为 this 阶段的值

    如果 consumer 执行过程中出现了异常,且 this 阶段本身未出现异常,则返回的 CompletionStage 将异常完成,且包含的异常为 consumer 执行过程中出现的异常

  • CompletionStage whenCompleteAsync(BiConsumer consumer):异步;this 阶段结束后,接着执行 consumer 的 accept() 方法,方法接收 this 阶段的结果(如果没有则为 null)和异常(如果没有则为 null)为参数;返回的 CompletionStage 中包含的值为 this 阶段的值

  • CompletionStage handle(BiFunction fn):同步;this 阶段结束后,接着执行 fn 的 apply() 方法,方法接收 this 阶段的结果(如果没有则为 null)和异常(如果没有则为 null)为参数;返回的 CompletionStage 中包含的值为 fn 执行结果

  • CompletionStage handleAsync(BiFunction fn):异步;this 阶段结束后,接着执行 fn 的 apply() 方法,方法接收 this 阶段的结果(如果没有则为 null)和异常(如果没有则为 null)为参数;返回的 CompletionStage 中包含的值为 fn 执行结果

参考

  • Java 并发编程实战