面试题:什么是 Java 的 CompletableFuture?

CompletableFuture 是 Java 8 引入的一个类,位于 java.util.concurrent 包中,它是对 Future 接口的扩展和增强。CompletableFuture 提供了一种更加灵活且强大的方式来处理异步编程任务,允许你以非阻塞的方式组合、转换以及处理异步结果。

主要特点

  1. 链式调用:通过一系列的方法(如 thenApply, thenAccept, thenCompose 等),可以轻松地将多个异步操作链接起来,形成一个异步操作流。
  2. 异常处理:提供了专门的方法(如 exceptionally, handle)用于处理异步计算过程中可能发生的异常,使得错误处理更加直观和方便。
  3. 组合多个 Future:支持多种方法(如 thenCombine, allOf, anyOf)来组合多个 CompletableFuture 实例的结果,便于同时等待多个异步操作完成或任意一个完成。
  4. 手动触发完成:与普通的 Future 不同,CompletableFuture 可以在创建时不绑定具体的异步任务,在后续根据需要手动触发其完成状态(使用 complete, completeExceptionally 方法)。

常见方法示例

  • 创建 CompletableFuture
  CompletableFuture<String> future = new CompletableFuture<>();
  • 基于已有任务创建 CompletableFuture
  CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
      System.out.println("Running async task.");
  });
  • 处理异步结果
  CompletableFuture.supplyAsync(() -> "Hello")
      .thenApply(s -> s + " World")
      .thenAccept(System.out::println); // 输出: Hello World
  • 异常处理
  CompletableFuture.supplyAsync(() -> {
      if (true) throw new RuntimeException("Test exception");
      return "Hello";
  }).exceptionally(ex -> {
      System.err.println("An error occurred: " + ex.getMessage());
      return "Default value";
  }).thenAccept(System.out::println); // 输出: An error occurred: Test exception 和 Default value
  • 组合多个 CompletableFuture
  CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> "Result1");
  CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> "Result2");

  CompletableFuture<Void> combinedFuture = CompletableFuture.allOf(future1, future2);
  combinedFuture.thenRun(() -> {
      try {
          String result1 = future1.get();
          String result2 = future2.get();
          System.out.println(result1 + " " + result2);
      } catch (Exception e) {
          e.printStackTrace();
      }
  });

使用场景

CompletableFuture 非常适合那些需要进行复杂的异步操作链,尤其是当你需要对异步操作的结果进行进一步处理或需要同时管理多个异步任务时。例如,在构建微服务架构中的客户端代码,或者在任何需要执行耗时操作(如网络请求、数据库查询等)而不想阻塞主线程的情况下都非常有用。

总之,CompletableFuture 提供了强大且灵活的方式来处理异步编程,极大地简化了编写并发程序的复杂度,并提高了代码的可读性和维护性。

THE END
喜欢就支持一下吧
点赞15 分享