CompletableFuture

本文介绍Java中CompletableFuture的基础用法及高级特性,包括如何创建CompletableFuture、处理异步任务依赖、合并多个异步任务等,帮助开发者更好地理解并利用CompletableFuture进行高效并发编程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

Future接口可以构建异步应用,但依然有其局限性。它很难直接表述多个Future 结果之间的依赖性。实际开发中,我们经常需要达成以下目的:

  • 将两个异步计算合并为一个——这两个异步计算之间相互独立,同时第二个又依赖于第一个的结果。
  • 等待 Future 集合中的所有任务都完成。
  • 仅等待 Future集合中最快结束的任务完成(有可能因为它们试图通过不同的方式计算同一个值),并返回它的结果。
  • 通过编程方式完成一个Future任务的执行(即以手工设定异步操作结果的方式)。
  • 应对 Future 的完成事件(即当 Future 的完成事件发生时会收到通知,并能使用 Future 计算的结果进行下一步的操作,不只是简单地阻塞等待操作的结果)

产生一个CompletableFuture

CompletableFuture中4个异步执行任务静态方法:

其中supplyAsync用于有返回值的任务,runAsync则用于没有返回值的任务。Executor参数可以手动指定线程池,否则默认ForkJoinPool.commonPool()系统级公共线程池,
注意:这些线程都是Daemon线程,主线程结束Daemon线程不结束,只有JVM关闭时,生命周期终止。

public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier) {
        return asyncSupplyStage(asyncPool, supplier);
    }
    
public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier,Executor executor) {
    return asyncSupplyStage(screenExecutor(executor), supplier);
}
    
public static CompletableFuture<Void> runAsync(Runnable runnable) {
    return asyncRunStage(asyncPool, runnable);
}
    
public static CompletableFuture<Void> runAsync(Runnable runnable, Executor executor) {
    return asyncRunStage(screenExecutor(executor), runnable);
}

thenApplyAsync

CompletableFuture<T> ,转换成 CompletableFuture<U>

CompletableFuture<Map<Integer, List<Long>>> completableFuture1 = futures[0];
return completableFuture1.thenApplyAsync(completableFuture1 -> {
    dosomething;
}, executor);

thenCombineAsync

将CompletableFuture<T> , CompletableFuture<U> 转换成 CompletableFuture<V>

CompletableFuture<Integer> completableFuture1 = futures[0];
CompletableFuture<String> completableFuture2 = futures[1];
        return completableFuture1.thenCombine(completableFuture1, (future1, future2) -> {
            Map<Integer, String> result = Maps.newHashMap();
            return result;
        });

allOf和anyOf

allOf是等待所有任务完成,构造后CompletableFuture完成

anyOf是只要有一个任务完成,构造后CompletableFuture就完成

参考

http://www.importnew.com/28319.html

 

https://blog.youkuaiyun.com/zero__007/article/details/50571703

https://blog.youkuaiyun.com/zero__007/article/details/50573562

https://blog.youkuaiyun.com/zero__007/article/details/50733664

 

### 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、付费专栏及课程。

余额充值