CompletableFuture介绍

1. CompletableFuture 简介

CompletableFuture 是 Java 8 引入的异步编程核心类,位于 java.util.concurrent 包中。它实现了 FutureCompletionStage 接口,提供了更强大的异步任务编排能力,支持链式调用、异常处理、任务组合等特性。与传统的 Future 相比,CompletableFuture 可以显式完成(complete)、支持异步回调(如 thenApply),并且可以组合多个任务。


2. 核心特性

  • 异步任务编排:通过链式调用(如 thenApplythenCompose)串联任务,形成有向无环图(DAG)。
  • 结果传递:前驱任务的结果会自动传递给后续任务。
  • 线程池控制:可指定自定义线程池执行任务,默认使用 ForkJoinPool.commonPool()
  • 异常处理:提供 exceptionally 和 handle 方法处理异常。
  • 任务组合:支持 allOf(等待所有任务完成)和 anyOf(任意一个任务完成即触发)。

3. 常用 API 和代码示例

3.1 创建异步任务
  • supplyAsync:创建带返回值的异步任务。

    CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> { // 模拟耗时操作 return "Hello, CompletableFuture!"; }); String result = future.join(); // 阻塞获取结果 System.out.println(result); // 输出:Hello, CompletableFuture!

  • runAsync:创建无返回值的异步任务。

    CompletableFuture<Void> future = CompletableFuture.runAsync(() -> { System.out.println("RunAsync Task is running..."); }); future.join(); // 等待任务完成

  • completedFuture:创建已完成的 CompletableFuture

    CompletableFuture<String> completedFuture = CompletableFuture.completedFuture("Cached Result"); System.out.println(completedFuture.join()); // 输出:Cached Result

3.2 结果转换与消费
  • thenApply:同步转换结果。

    CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> "Hello"); CompletableFuture<String> transformedFuture = future.thenApply(s -> s + " World"); System.out.println(transformedFuture.join()); // 输出:Hello World

  • thenApplyAsync:异步转换结果(默认使用 ForkJoinPool.commonPool())。

    CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> "Hello"); CompletableFuture<String> transformedFuture = future.thenApplyAsync(s -> s.toUpperCase()); System.out.println(transformedFuture.join()); // 输出:HELLO WORLD

  • thenAccept:同步消费结果(无返回值)。

    CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> "Message"); future.thenAccept(s -> System.out.println("Consumed: " + s));

  • thenRun:同步执行无输入的任务。

    CompletableFuture<Void> future = CompletableFuture.runAsync(() -> System.out.println("Task 1")); future.thenRun(() -> System.out.println("Task 2"));

3.3 任务组合
  • thenCombine:合并两个任务的结果。

    CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> "Hello"); CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> "World"); CompletableFuture<String> combinedFuture = future1.thenCombine(future2, (s1, s2) -> s1 + " " + s2); System.out.println(combinedFuture.join()); // 输出:Hello World

  • allOf:等待所有任务完成。

    CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> "Task 1"); CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> "Task 2"); CompletableFuture<Void> allOfFuture = CompletableFuture.allOf(future1, future2); allOfFuture.join(); // 等待所有任务完成 System.out.println("All tasks completed");

  • anyOf:任意一个任务完成即触发。

    
    

    CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> { try { TimeUnit.SECONDS.sleep(2); } catch (InterruptedException e) {} return "Task 1"; }); CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> { try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) {} return "Task 2"; }); CompletableFuture<Object> anyOfFuture = CompletableFuture.anyOf(future1, future2); System.out.println("First completed task: " + anyOfFuture.join()); // 输出:Task 2

3.4 异常处理
  • exceptionally:捕获异常并返回默认值。

    
    

    CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> { throw new RuntimeException("Failed!"); }).exceptionally(ex -> "Fallback Value"); System.out.println(future.join()); // 输出:Fallback Value

  • handle:无论成功或失败均处理结果。

    
    

    CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> { if (new Random().nextBoolean()) { throw new RuntimeException("Error!"); } return "Success"; }).handle((result, ex) -> { if (ex != null) { return "Handled Exception: " + ex.getMessage(); } return "Handled Result: " + result; }); System.out.println(future.join());

3.5 手动完成与超时控制
  • 手动完成

    
    

    CompletableFuture<String> manualFuture = new CompletableFuture<>(); manualFuture.complete("Manual Result"); // 手动完成 System.out.println(manualFuture.join()); // 输出:Manual Result

  • 超时控制(JDK 9+):

    
    

    CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> { try { TimeUnit.SECONDS.sleep(5); } catch (InterruptedException e) {} return "Result"; }).completeOnTimeout("Timeout", 3, TimeUnit.SECONDS); // 3秒后超时 System.out.println(future.join()); // 输出:Timeout


4. 高级使用场景

4.1 自定义线程池

ExecutorService customPool = Executors.newFixedThreadPool(4); CompletableFuture<Void> future = CompletableFuture.runAsync(() -> { // 执行任务 }, customPool); customPool.shutdown(); // 关闭线程池

4.2 响应式流水线

CompletableFuture.supplyAsync(this::fetchOrder) .thenApplyAsync(this::validateOrder, validationPool) .thenComposeAsync(this::processPayment, paymentPool) .exceptionally(ex -> handleError(ex));


5. 总结

CompletableFuture 提供了强大的异步编程能力,适用于以下场景:

  • 异步任务编排:通过链式调用描述复杂的任务依赖关系。
  • 非阻塞操作:避免使用 get() 阻塞主线程,保持高响应性。
  • 异常处理:内置异常处理机制,避免异常丢失。
  • 多任务协同:支持 allOfanyOf 等组合操作。

最佳实践

  • 尽量使用 thenApply 替代 get(),保持异步非阻塞。
  • 为不同任务类型(CPU/IO 密集型)使用独立的线程池。
  • 及时关闭自定义线程池,防止资源泄漏。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值