当前位置: 首页 > news >正文

CompletableFuture常见的java场景

CompletableFuture 是 Java 8 引入的一个非常强大的工具,用于编写异步、非阻塞的代码。它代表了未来某个时刻会完成的计算结果,并提供了丰富的 API 来组合、转换和处理异步任务。

核心场景一:执行耗时任务(避免阻塞主线程)

这是最基础的用途。当你有一个耗时的操作(如IO、网络请求、复杂计算)时,不希望它阻塞当前线程(特别是UI线程或服务器的主请求线程),就可以使用 CompletableFuture 将其提交到另一个线程中异步执行。

示例:异步计算并获取结果

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;public class BasicExample {public static void main(String[] args) throws ExecutionException, InterruptedException {// 1. 使用 supplyAsync 执行一个有返回值的异步任务CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {// 模拟一个耗时2秒的任务try {Thread.sleep(2000);} catch (InterruptedException e) {throw new IllegalStateException(e);}return "任务执行结果";});// 主线程可以继续做其他事情,不会被阻塞System.out.println("主线程可以继续执行...");// 2. 阻塞地等待异步任务完成并获取结果(在实际应用中应尽量避免阻塞)String result = future.get();System.out.println("获取到结果: " + result);}
}

核心场景二:组合多个异步任务(链式调用)

这是 CompletableFuture 最强大的地方。你可以定义一个任务完成之后,紧接着执行另一个任务,形成一条异步流水线。

示例:第一个任务的结果是第二个任务的输入

CompletableFuture<String> welcomeText = CompletableFuture.supplyAsync(() -> {// 模拟从数据库获取用户IDtry { Thread.sleep(500); } catch (InterruptedException e) { }return "User123";
}).thenApply(userId -> {// 根据用户ID获取用户详细信息return userId + " 的详细信息";
}).thenApply(userInfo -> {// 组装欢迎信息return "您好, " + userInfo;
});
System.out.println(welcomeText.get()); // 输出: 您好, User123 的详细信息

关键方法:

  • thenApply(): 接收上一个任务的结果,进行处理并返回新值(同步操作)。
  • thenCompose(): 接收上一个任务的结果,并返回一个新的 CompletableFuture(用于链接另一个异步任务)。

核心场景三:聚合多个并行任务(全部完成或任一完成)

当你需要并行执行多个独立的任务,并在它们都完成后(或其中一个完成后)进行后续处理时,这个功能非常有用。

示例:并行调用多个外部API,并聚合它们的结果

// 模拟三个不同的API调用
CompletableFuture<String> api1 = CompletableFuture.supplyAsync(() -> callAPI("https://api.users.com"));
CompletableFuture<String> api2 = CompletableFuture.supplyAsync(() -> callAPI("https://api.products.com"));
CompletableFuture<String> api3 = CompletableFuture.supplyAsync(() -> callAPI("https://api.orders.com"));// 1. 等待所有任务完成
CompletableFuture<Void> allFutures = CompletableFuture.allOf(api1, api2, api3);// 在所有任务完成后,获取它们的结果
CompletableFuture<List<String>> allResults = allFutures.thenApply(v -> Stream.of(api1, api2, api3).map(CompletableFuture::join) // 在这里调用join是安全的,因为所有future已完成
          .collect(Collectors.toList())
);allResults.thenAccept(results -> System.out.println("所有API结果: " + results));// 2. 等待任意一个任务完成
CompletableFuture<Object> anyFuture = CompletableFuture.anyOf(api1, api2, api3);
anyFuture.thenAccept(result -> System.out.println("最快返回的API结果: " + result));

关键方法:

  • allOf(): 等待所有给定的 CompletableFuture 完成。
  • anyOf(): 等待任意一个给定的 CompletableFuture 完成。

核心场景四:异常处理
异步流水线中的异常不能被传统的 try-catch 捕获,CompletableFuture 提供了专门的异常处理方法。

示例:优雅地处理异步任务中的异常

CompletableFuture.supplyAsync(() -> {// 模拟一个可能失败的任务if (Math.random() > 0.5) {throw new RuntimeException("Oops! Something went wrong!");}return "Success";
}).exceptionally(ex -> {// 如果发生异常,会进入这里,并提供一个默认值或恢复方案System.out.println("处理异常: " + ex.getMessage());return "Default Value"; // 从异常中恢复
}).thenAccept(result -> {// 无论成功还是失败(已处理),都会走到这里System.out.println("最终结果: " + result);
});

关键方法:

  • exceptionally(): 相当于 catch,允许你捕获异常并返回一个默认值。
  • handle(): 无论成功还是失败都会调用,方法接收结果和异常两个参数,让你可以统一处理。

核心场景五:结果消费(无需返回值的后续操作)
当你不需要返回新值,只是想在上一个任务完成后执行一些操作(如日志记录、发送通知),可以使用 thenAccept 或 thenRun。

示例:用户注册后发送欢迎邮件

CompletableFuture.supplyAsync(() -> {// 1. 执行用户注册逻辑return registerUser();
}).thenAccept(user -> {// 2. 注册成功后,使用用户信息发送邮件(消费上一步的结果)
    sendWelcomeEmail(user);
}).thenRun(() -> {// 3. 无论成功失败,最后记录日志(不消费任何结果)System.out.println("用户注册流程结束。");
});

关键方法:

  • thenAccept(): 接收上一个任务的结果,进行消费(无返回值)。
  • thenRun(): 既不接收上一个任务的结果,也不返回任何值,只是在一个任务完成后执行一段代码。

总结:何时使用 CompletableFuture

image

它非常适合用于构建高性能、高并发的服务,例如微服务架构中同时调用多个下游服务并聚合结果的场景。它是传统 Future 的强大升级,提供了非阻塞的回调式编程模型。

http://www.jsqmd.com/news/36662/

相关文章:

  • D - Deductive Snooker Scoring
  • MySQL性能优化|InnoDB存储引擎深度解析:从表空间到数据行的设计哲学 - 指南
  • 从零开始的C++学习生活 7:vector的入门使用 - 教程
  • .net9 BundlerMinifier与StaticWebAssets冲突
  • 淘宝店铺全量商品接口实战:分类穿透采集与增量同步的技术方案
  • 分治+字符串(p3612)
  • Python详细学习教程
  • ubuntu 安装使用 qemu
  • TypeScript 中的策略模式
  • NProgress 给 Vue 路由切换加个 “假” 进度条提升用户体验
  • 2025年钢结构艺术造型直销厂家权威推荐榜单:钢结构景观造型/艺术钢结构/扭曲螺旋钢结构艺术造型源头厂家精选
  • 伊克罗德信息成为 Dify 官方代理商,携手共创企业级 Agentic AI 应用新未来!
  • 数组的定义、访问、输出
  • 2025年沼气直燃品牌综合评测:徐州海德测控领跑行业
  • 2025年沼气直燃生产厂家实力对比:徐州海德测控领跑
  • 2025年市场低氮燃烧器供应商前十强
  • 2025年沼气直燃品牌排名前十:徐州海德测控领跑行业创新
  • 2025年低氮燃烧器制造企业top10:行业排名与深度解析
  • 封装电气性能新径
  • 在Docker中live-restore
  • 11月10日打卡
  • 2025年11月安徽省矿用设备安全检测检验企业口碑榜
  • 从局部性原理到一致性模型:深入剖析缓存设计的核心权衡
  • P3625 采油区域-分类讨论
  • 12345A 景区 区别
  • 2025年贴标机生产厂家前十强权威排名:彩航包装领跑行业
  • FastApi Linux 部署
  • 方格染色-并查集
  • 逆向基础--数据传输指令mov和xchg (10)
  • P8186-传递闭包