目录
🎪 组合任务:CompletableFuture的真正威力!
还在为层层嵌套的回调地狱而头疼?CompletableFuture让你用优雅的方式驾驭异步编程!
🚀 什么是CompletableFuture?
想象一下这个场景:你要做一顿丰盛的晚餐,需要同时煮饭、炒菜、烧汤。如果傻傻地等饭煮完再炒菜,等菜炒完再烧汤,估计客人早就饿跑了!
CompletableFuture就是你的超级厨房管家,它能帮你同时开展多个任务,并在任务完成后智能地组合结果,让你的程序效率提升数倍!
⚡ 快速上手:创建异步任务
基础用法(够简单!)
// 无返回值任务 - 就像让助手去倒垃圾
CompletableFuture<Void> trashTask = CompletableFuture.runAsync(() -> {
System.out.println("🗑️ 正在倒垃圾...");
});
// 有返回值任务 - 就像让助手去买咖啡,还要把咖啡带回来
CompletableFuture<String> coffeeTask = CompletableFuture.supplyAsync(() -> {
return "☕ 香浓的拿铁";
});
进阶技巧:自定义线程池
// 为什么要自定义?默认线程池就像公共食堂,人多了就排队!
ExecutorService myExecutor = Executors.newFixedThreadPool(5);
CompletableFuture<String> vipTask = CompletableFuture.supplyAsync(() -> {
return "🎯 VIP任务执行完毕";
}, myExecutor); // 专属线程池,享受VIP通道!
🎯 处理结果的三种姿势
任务执行完了,怎么优雅地拿到结果?
1. thenApply - 对结果再加工
java
CompletableFuture<String> rawMaterial = CompletableFuture.supplyAsync(() -> "生米");
// 把生米煮成熟饭
CompletableFuture<String> cookedRice = rawMaterial.thenApply(material -> material + " → 香喷喷的米饭");
System.out.println(cookedRice.join()); // 输出:生米 → 香喷喷的米饭
2. thenAccept - 消费结果
// 就像收到外卖直接开吃,不需要再加工
coffeeTask.thenAccept(coffee -> System.out.println("😋 享受:" + coffee));
3. thenRun - 任务完成后的清理
// 不管任务结果如何,完成后都要执行
coffeeTask.thenRun(() -> System.out.println("🧹 清理咖啡机"));
🎪 组合任务:CompletableFuture的真正威力!
这才是让你从青铜到王者的关键技能!
场景1:任务串联(一个接一个)
CompletableFuture<String> hello = CompletableFuture.supplyAsync(() -> "Hello");
// thenCompose:把前一个任务的结果喂给下一个任务
CompletableFuture<String> greeting = hello.thenCompose(s ->
CompletableFuture.supplyAsync(() -> s + " World! 👋")
);
System.out.println(greeting.join()); // 输出:Hello World! 👋
场景2:任务并行(同时开工再合并)
CompletableFuture<String> riceTask = CompletableFuture.supplyAsync(() -> "米饭");
CompletableFuture<String> dishTask = CompletableFuture.supplyAsync(() -> "红烧肉");
// thenCombine:两个任务都完成后,合并成果
CompletableFuture<String> dinner = riceTask.thenCombine(dishTask, (rice, dish) ->
"🍽️ 晚餐准备好了:" + rice + " + " + dish
);
System.out.println(dinner.join()); // 输出:🍽️ 晚餐准备好了:米饭 + 红烧肉
场景3:等待所有任务完成
CompletableFuture<String> task1 = CompletableFuture.supplyAsync(() -> "打扫房间");
CompletableFuture<String> task2 = CompletableFuture.supplyAsync(() -> "洗衣服");
CompletableFuture<Void> allTasks = CompletableFuture.allOf(task1, task2);
allTasks.thenRun(() -> {
// 所有家务都完成了!
System.out.println("🎉 所有任务完成!");
System.out.println("任务1:" + task1.join());
System.out.println("任务2:" + task2.join());
});
场景4:谁快用谁(竞速模式)
java
CompletableFuture<String> fastTask = CompletableFuture.supplyAsync(() -> {
try { Thread.sleep(100); } catch (InterruptedException e) {}
return "🚀 闪电侠完成任务";
});
CompletableFuture<String> slowTask = CompletableFuture.supplyAsync(() -> {
try { Thread.sleep(500); } catch (InterruptedException e) {}
return "🐢 乌龟完成任务";
});
// anyOf:谁先完成就用谁的结果
CompletableFuture<Object> winner = CompletableFuture.anyOf(fastTask, slowTask);
System.out.println("冠军是:" + winner.join()); // 输出:冠军是:🚀 闪电侠完成任务
🚑 异常处理:不怕任务出幺蛾子
方式1:exceptionally - 优雅降级
CompletableFuture<String> riskyTask = CompletableFuture.supplyAsync(() -> {
if (Math.random() > 0.5) {
throw new RuntimeException("💥 任务爆炸了!");
}
return "🎁 任务成功";
});
// 即使任务失败,也有备选方案
CompletableFuture<String> safeTask = riskyTask.exceptionally(ex -> {
System.out.println("🛡️ 任务失败,启动备用方案");
return "📦 默认结果";
});
方式2:handle - 统一处理成败
CompletableFuture<String> task = CompletableFuture.supplyAsync(() -> "正常执行");
CompletableFuture<String> handled = task.handle((result, exception) -> {
if (exception != null) {
return "❌ 处理异常:" + exception.getMessage();
}
return "✅ 处理成功:" + result;
});
💼 实战案例:用户信息查询
来看一个真实的生产场景:
// 模拟服务类
class UserService {
public User getUser(String userId) {
return new User(userId, "张三"); // 模拟数据库查询
}
}
class OrderService {
public List<Order> getOrders(String userId) {
return Arrays.asList(new Order("订单1"), new Order("订单2"));
}
}
// 🎯 异步查询实现
UserService userService = new UserService();
OrderService orderService = new OrderService();
String userId = "123";
// 并行查询:用户信息和订单信息同时进行!
CompletableFuture<User> userFuture = CompletableFuture.supplyAsync(() ->
userService.getUser(userId)
);
CompletableFuture<List<Order>> ordersFuture = CompletableFuture.supplyAsync(() ->
orderService.getOrders(userId)
);
// 智能组合:两个查询都完成后,合并结果
userFuture.thenCombine(ordersFuture, (user, orders) -> {
user.setOrders(orders); // 设置用户订单
return user;
}).thenAccept(user -> {
System.out.println("👤 用户详情:" + user);
System.out.println("📦 订单数量:" + user.getOrders().size());
}).exceptionally(ex -> {
System.out.println("😱 查询失败:" + ex.getMessage());
return null;
});
⚠️ 避坑指南
-
线程池选择:高并发场景一定要用自定义线程池
-
避免阻塞:多用回调,少用
get()/join() -
异常处理:每个链式操作都要考虑异常情况
-
资源释放:自定义线程池用完记得关闭
🎯 总结
CompletableFuture让异步编程变得如此简单:
-
✅ 创建任务:
supplyAsync()/runAsync() -
✅ 处理结果:
thenApply()/thenAccept()/thenRun() -
✅ 组合任务:
thenCompose()/thenCombine()/allOf()/anyOf() -
✅ 异常处理:
exceptionally()/handle()
记住这个异步编程心法:
任务并行效率高,回调组合真巧妙
异常处理要到位,线程管理不能少
💬 互动话题:在你的项目中,哪些场景可以用CompletableFuture优化?在评论区分享你的想法,我们一起讨论!
❤️ 温馨提示:如果觉得有用,记得点赞收藏哦~ 关注我,解锁更多Java黑科技!
1147

被折叠的 条评论
为什么被折叠?



