CompletableFuture

本文探讨了Future在异步编程中的局限性,并介绍了如何使用Future实现复杂的异步任务合并,包括等待多个Future完成、选择最快完成的任务、手动设置Future结果及处理Future完成事件的策略。

Future有一定的局限性,无法实现某些场景的异步处理

  • 两个异步计算合并为一个(这两个异步计算之间相互独立,同时第二个又依赖于第一个的结果).
  • 等待Future集合中的所有任务都完成.
  • 仅等待Future集合中最快结束的任务完成(有可能因为它们试图通过不同的方式计算同一个值),并返回它的结果.
  • 通过编程方式完成一个Future任务的执行(即以手工设定异步操作结果的方式).
  • 应对Future的完成事件(即当Future的完成事件发生时会收到通知,并能使用Future计算的结果进行下一步的操作,不只是简单地阻塞等待操作的结果).
### CompletableFuture 的用法及错误处理 CompletableFuture 是 Java 8 引入的一个强大工具,用于处理异步编程和复杂的任务链。它不仅支持异步执行任务,还提供了丰富的 API 来处理任务的结果或异常。 #### 基本概念 CompletableFuture 是一个 Future 的增强版本,允许开发者通过回调函数来处理任务完成后的结果或异常[^1]。它支持多种方法来组合多个异步任务,例如 `thenApply`、`thenAccept`、`exceptionally` 等。 #### 创建 CompletableFuture 可以使用以下几种方式创建 CompletableFuture: - 使用 `runAsync` 方法运行不返回结果的任务。 ```java CompletableFuture<Void> future = CompletableFuture.runAsync(() -> { System.out.println("Running in a separate thread: " + Thread.currentThread().getName()); }); future.join(); // Wait for the task to complete ``` - 使用 `supplyAsync` 方法运行返回结果的任务。 ```java CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> { return "Result from supplyAsync"; }); System.out.println(future.join()); // Output the result ``` #### 链式调用 CompletableFuture 支持链式调用来处理任务的结果或异常。例如: - `thenApply`:对前一个任务的结果进行转换。 ```java CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> "Hello") .thenApply(s -> s + " World"); System.out.println(future.join()); // Output: Hello World ``` - `thenAccept`:消费前一个任务的结果。 ```java CompletableFuture.supplyAsync(() -> "Hello World") .thenAccept(System.out::println); ``` - `thenCompose`:将一个 CompletableFuture 的结果作为另一个 CompletableFuture 的输入。 ```java CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> "Hello") .thenCompose(s -> CompletableFuture.supplyAsync(() -> s + " World")); System.out.println(future.join()); // Output: Hello World ``` #### 错误处理 当任务抛出异常时,可以使用 `exceptionally` 或 `handle` 方法来捕获并处理异常。 - `exceptionally`:为任务的异常提供一个默认值。 ```java CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> { throw new RuntimeException("Task failed"); }).exceptionally(ex -> "Default Value on Exception: " + ex.getMessage()); System.out.println(future.join()); // Output: Default Value on Exception: Task failed ``` - `handle`:为任务的成功或失败提供统一的处理逻辑。 ```java CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> { throw new RuntimeException("Task failed"); }).handle((result, ex) -> { if (ex != null) { return "Handled Exception: " + ex.getMessage(); } return "Result: " + result; }); System.out.println(future.join()); // Output: Handled Exception: Task failed ``` #### 并行任务 可以通过 `allOf` 和 `anyOf` 方法来组合多个 CompletableFuture。 - `allOf`:等待所有任务完成。 ```java CompletableFuture<Void> allFutures = CompletableFuture.allOf( CompletableFuture.runAsync(() -> System.out.println("Task 1")), CompletableFuture.runAsync(() -> System.out.println("Task 2")) ); allFutures.join(); // Wait for both tasks to complete ``` - `anyOf`:等待任意一个任务完成。 ```java CompletableFuture<Object> anyFuture = CompletableFuture.anyOf( CompletableFuture.supplyAsync(() -> { try { TimeUnit.SECONDS.sleep(2); } catch (InterruptedException e) {} return "Task 1"; }), CompletableFuture.supplyAsync(() -> { try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) {} return "Task 2"; }) ); System.out.println(anyFuture.join()); // Output: Task 2 ``` #### 实际应用 在实际开发中,CompletableFuture 可以用于异步加载数据、并发任务调度等场景。例如,结合数据库查询和缓存操作: ```java CompletableFuture<String> dbFuture = CompletableFuture.supplyAsync(() -> { // Simulate database query try { TimeUnit.SECONDS.sleep(2); } catch (InterruptedException e) {} return "Data from DB"; }); CompletableFuture<String> cacheFuture = CompletableFuture.supplyAsync(() -> { // Simulate cache lookup try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) {} return "Data from Cache"; }); CompletableFuture<Void> combinedFuture = dbFuture.thenAcceptBoth(cacheFuture, (dbResult, cacheResult) -> { System.out.println("DB Result: " + dbResult); System.out.println("Cache Result: " + cacheResult); }); combinedFuture.join(); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值