CompletableFuture:让你的Java代码飞起来的异步编程神器!

目录

🚀 什么是CompletableFuture?

⚡ 快速上手:创建异步任务

基础用法(够简单!)

进阶技巧:自定义线程池

🎯 处理结果的三种姿势

1. thenApply - 对结果再加工

2. thenAccept - 消费结果

3. thenRun - 任务完成后的清理

🎪 组合任务:CompletableFuture的真正威力!

场景1:任务串联(一个接一个)

场景2:任务并行(同时开工再合并)

场景3:等待所有任务完成

场景4:谁快用谁(竞速模式)

🚑 异常处理:不怕任务出幺蛾子

方式1:exceptionally - 优雅降级

方式2:handle - 统一处理成败

💼 实战案例:用户信息查询

⚠️ 避坑指南

🎯 总结


还在为层层嵌套的回调地狱而头疼?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;
});

⚠️ 避坑指南

  1. 线程池选择:高并发场景一定要用自定义线程池

  2. 避免阻塞:多用回调,少用get()/join()

  3. 异常处理:每个链式操作都要考虑异常情况

  4. 资源释放:自定义线程池用完记得关闭

🎯 总结

CompletableFuture让异步编程变得如此简单:

  • ✅ 创建任务supplyAsync() / runAsync()

  • ✅ 处理结果thenApply() / thenAccept() / thenRun()

  • ✅ 组合任务thenCompose() / thenCombine() / allOf() / anyOf()

  • ✅ 异常处理exceptionally() / handle()

记住这个异步编程心法

任务并行效率高,回调组合真巧妙
异常处理要到位,线程管理不能少


💬 互动话题:在你的项目中,哪些场景可以用CompletableFuture优化?在评论区分享你的想法,我们一起讨论!

❤️ 温馨提示:如果觉得有用,记得点赞收藏哦~ 关注我,解锁更多Java黑科技!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不debug的程序员

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值