CompletableFuture 异步编程学习笔记
📚 目录
🎯 基础概念
什么是 Future?
该如何理解Future呢?举个生活中的例子:
你去咖啡店点了一杯咖啡,然后服务员会给你一个订单小票。 当服务员在后台制作咖啡的时候,你并没有在店里等待,而是出门到隔壁甜品店又买了个面包。 当面包买好之后,你回到咖啡店,拿着订单小票去取咖啡。 取到咖啡后,你边喝咖啡边把面包吃了……嗝~
是不是很熟悉的生活场景? 对比到我们多线程异步编程的场景中,咖啡店的订单小票其实就是Future,通过Future可以让稍后适当的时候可以获取到对应的异步执行线程中的执行结果。
上面的场景,我们翻译为代码实现逻辑:
public void buyCoffeeAndOthers() throws ExecutionException, InterruptedException {
goShopping();
// 子线程中去处理做咖啡这件事,返回future对象
Future<Coffee> coffeeTicket = threadPool.submit(this::makeCoffee);
// 主线程同步去做其他的事情
Bread bread = buySomeBread();
// 主线程其他事情并行处理完成,阻塞等待获取子线程执行结果
Coffee coffee = coffeeTicket.get();
// 子线程结果获取完成,主线程继续执行
eatAndDrink(bread, coffee);
}
什么是 CompletableFuture?
CompletableFuture 是 Java 8 引入的异步编程工具,用于处理异步任务和组合多个异步操作。
核心特点
- ✅ 链式调用 - 支持流畅的方法链
- ✅ 异步执行 - 不阻塞主线程
- ✅ 组合能力 - 可以组合多个异步任务
- ✅ 异常处理 - 内置异常处理机制
🔄 Future vs CompletableFuture
| 特性 | Future | CompletableFuture |
|---|---|---|
| 创建方式 | 需要线程池 + Callable | 直接静态方法创建 |
| 获取结果 | get() 阻塞等待 | get() / join() |
| 异常处理 | 需要 try-catch | 内置 handle() / whenComplete() |
| 组合能力 | ❌ 无 | ✅ 丰富的组合方法 |
| 链式调用 | ❌ 无 | ✅ 支持 |
代码对比
FutureTask 方式(传统)
// 需要手动管理线程池
ExecutorService executor = Executors.newFixedThreadPool(10);
FutureTask<UserInfo> userTask = new FutureTask<>(() -> {
return userService.getUserInfo(userId);
});
executor.submit(userTask);
FutureTask<MedalInfo> medalTask = new FutureTask<>(() -> {
return medalService.getMedalInfo(userId);
});
executor.submit(medalTask);
// 阻塞获取结果
UserInfo userInfo = userTask.get();
MedalInfo medalInfo = medalTask.get();
executor.shutdown(); // 需要手动关闭
CompletableFuture 方式(现代)
// 自动使用 ForkJoinPool,无需手动管理线程池
CompletableFuture<UserInfo> userFuture = CompletableFuture.supplyAsync(() ->
userService.getUserInfo(userId)
);
CompletableFuture<MedalInfo> medalFuture = CompletableFuture.supplyAsync(() ->
medalService.getMedalInfo(userId)
);
// 组合结果
CompletableFuture<String> result = userFuture.thenCombine(medalFuture,
(user, medal) -> "用户: " + user + ", 勋章: " + medal
);
System.out.println(result.get());
🛠️ 核心方法详解
1. 创建异步任务
| 方法 | 参数类型 | 返回值 | 用途 |
|---|---|---|---|
runAsync() | Runnable | CompletableFuture<Void> | 无返回值的异步任务 |
supplyAsync() | Supplier<T> | CompletableFuture<T> | 有返回值的异步任务 |
// 无返回值
CompletableFuture<Void> runFuture = CompletableFuture.runAsync(() -> {
System.out.println("执行任务");
});
// 有返回值
CompletableFuture<String> supplyFuture = CompletableFuture.supplyAsync(() -> {
return "任务结果";
});
2. 链式处理方法
| 方法 | 输入 | 输出 | 用途 | 记忆技巧 |
|---|---|---|---|---|
thenApply | ✅ 有 | ✅ 有 | 转换结果 | Apply = 应用转换 |
thenCompose | ✅ 有 | ✅ CompletableFuture | 组合异步操作 | Compose = 组合 |
thenAccept | ✅ 有 | ❌ 无 | 消费结果 | Accept = 接受消费 |
thenRun | ❌ 无 | ❌ 无 | 执行后续操作 | Run = 运行 |
示例代码
CompletableFuture.supplyAsync(() -> "原始数据")
.thenApply(data -> "处理后的" + data) // 转换
.thenCompose(data -> CompletableFuture.supplyAsync(() ->
"异步处理" + data)) // 组合异步
.thenAccept(result -> System.out.println(result)) // 消费
.thenRun(() -> System.out.println("清理工作")); // 后续操作
3. 获取结果
| 方法 | 异常处理 | 使用场景 |
|---|---|---|
get() | 受检异常,需要 try-catch | 需要精确异常处理 |
join() | 运行时异常,无需 try-catch | 大多数情况,代码更简洁 |
// get() - 需要异常处理
try {
String result = future.get();
} catch (ExecutionException | InterruptedException e) {
e.printStackTrace();
}
// join() - 更简洁
String result = future.join();
🚨 异常处理方法
handle vs whenComplete
| 特性 | handle | whenComplete |
|---|---|---|
| 输入 | ✅ 结果 + 异常 | ✅ 结果 + 异常 |
| 输出 | ✅ 可以返回新结果 | ❌ 无返回值 |
| 异常处理 | ✅ 可以恢复异常 | ❌ 只能观察异常 |
| 返回类型 | CompletableFuture<U> | CompletableFuture<T> |
| 用途 | 异常恢复、结果转换 | 日志记录、监控 |
handle - 异常恢复器
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
throw new RuntimeException("出错了");
});
CompletableFuture<String> handled = future.handle((result, ex) -> {
if (ex != null) {
return "默认值"; // 🔥 异常恢复
}
return result;
});
System.out.println(handled.get()); // 输出: 默认值
whenComplete - 观察者
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
throw new RuntimeException("出错了");
});
CompletableFuture<String> observed = future.whenComplete((result, ex) -> {
if (ex != null) {
System.out.println("记录异常日志: " + ex.getMessage());
}
// 🔥 不能改变结果,异常依然存在
});
// observed.get() 依然会抛出异常
▶️ Demo - 基础
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
public class CompletableFutureMethodsDemo {
public static void main(String[] args) throws ExecutionException, InterruptedException {
System.out.println("=== CompletableFuture 四大方法详解 ===\n");
// 1. thenApply - 转换结果(有输入,有输出)
System.out.println("1. thenApply - 转换结果");
CompletableFuture<String> nameFuture = CompletableFuture.supplyAsync(() -> {
System.out.println(" 获取用户名...");
return "张三";
});
CompletableFuture<String> greetingFuture = nameFuture.thenApply(name -> {
System.out.println(" 转换用户名为问候语...");
return "你好, " + name + "!"; // 输入 name,输出新的字符串
});
System.out.println(" 结果: " + greetingFuture.get());
System.out.println();
// 2. thenCompose - 组合异步操作(有输入,返回新的 CompletableFuture)
System.out.println("2. thenCompose - 组合异步操作");
CompletableFuture<String> userIdFuture = CompletableFuture.supplyAsync(() -> {
System.out.println(" 获取用户ID...");
return "123";
});
CompletableFuture<String> userDetailFuture = userIdFuture.thenCompose(userId -> {
System.out.println(" 根据用户ID异步获取用户详情...");
return CompletableFuture.supplyAsync(() -> {
// 这里返回的是一个新的 CompletableFuture
return "用户详情: ID=" + userId + ", 姓名=李四";
});
});
System.out.println(" 结果: " + userDetailFuture.get());
System.out.println();
// 3. thenAccept - 消费结果(有输入,无输出)
System.out.println("3. thenAccept - 消费结果");
CompletableFuture<String> messageFuture = CompletableFuture.supplyAsync(() -> {
System.out.println(" 生成消息...");
return "重要通知";
});
CompletableFuture<Void> printFuture = messageFuture.thenAccept(message -> {
System.out.println(" 处理消息: " + message);
System.out.println(" 消息已发送到用户手机");
// 注意:这里没有 return 语句,只是消费结果
});
printFuture.get(); // 等待完成
System.out.println(" thenAccept 返回值: " + printFuture.get()); // 输出 null
System.out.println();
// 4. thenRun - 执行后续操作(无输入,无输出)
System.out.println("4. thenRun - 执行后续操作");
CompletableFuture<String> taskFuture = CompletableFuture.supplyAsync(() -> {
System.out.println(" 执行主要任务...");
return "任务完成";
});
CompletableFuture<Void> cleanupFuture = taskFuture.thenRun(() -> {
System.out.println(" 清理资源...");
System.out.println(" 发送完成通知...");
// 注意:这里不关心前面任务的结果,只是在任务完成后执行
});
cleanupFuture.get(); // 等待完成
System.out.println(" thenRun 返回值: " + cleanupFuture.get()); // 输出 null
System.out.println();
// 综合示例:链式调用
System.out.println("5. 综合示例 - 链式调用");
CompletableFuture<Void> chainFuture = CompletableFuture
.supplyAsync(() -> {
System.out.println(" 步骤1: 获取原始数据");
return "原始数据";
})
.thenApply(data -> {
System.out.println(" 步骤2: 处理数据 - " + data);
return "处理后的数据";
})
.thenCompose(processedData -> {
System.out.println(" 步骤3: 异步保存数据 - " + processedData);
return CompletableFuture.supplyAsync(() -> "保存成功");
})
.thenAccept(result -> {
System.out.println(" 步骤4: 记录日志 - " + result);
})
.thenRun(() -> {
System.out.println(" 步骤5: 清理临时文件");
});
chainFuture.get();
System.out.println(" 链式调用完成!");
System.out.println();
// 6. handle - 处理结果和异常(有输入,有输出)
System.out.println("6. handle - 处理结果和异常");
// 正常情况
CompletableFuture<String> successFuture = CompletableFuture.supplyAsync(() -> {
System.out.println(" 执行正常任务...");
return "成功结果";
});
CompletableFuture<String> handledSuccessFuture = successFuture.handle((result, exception) -> {
if (exception != null) {
System.out.println(" 处理异常: " + exception.getMessage());
return "默认值";
} else {
System.out.println(" 处理正常结果: " + result);
return "处理后的" + result;
}
});
System.out.println(" handle 正常结果: " + handledSuccessFuture.get());
// 异常情况
CompletableFuture<String> errorFuture = CompletableFuture.supplyAsync(() -> {
System.out.println(" 执行会出错的任务...");
throw new RuntimeException("模拟异常");
});
CompletableFuture<String> handledErrorFuture = errorFuture.handle((result, exception) -> {
if (exception != null) {
System.out.println(" 捕获并处理异常: " + exception.getMessage());
return "异常恢复值";
} else {
System.out.println(" 处理正常结果: " + result);
return result;
}
});
System.out.println(" handle 异常结果: " + handledErrorFuture.get());
System.out.println();
// 7. whenComplete - 完成时回调(有输入,无输出,不改变结果)
System.out.println("7. whenComplete - 完成时回调");
// 正常情况
CompletableFuture<String> normalTask = CompletableFuture.supplyAsync(() -> {
System.out.println(" 执行正常任务...");
return "任务结果";
});
CompletableFuture<String> whenCompleteNormal = normalTask.whenComplete((result, exception) -> {
if (exception != null) {
System.out.println(" whenComplete - 任务异常: " + exception.getMessage());
} else {
System.out.println(" whenComplete - 任务完成,结果: " + result);
System.out.println(" 记录日志、发送通知等...");
}
// 注意:whenComplete 不能改变结果,只能观察
});
System.out.println(" whenComplete 正常结果: " + whenCompleteNormal.get());
// 异常情况
CompletableFuture<String> errorTask = CompletableFuture.supplyAsync(() -> {
System.out.println(" 执行会出错的任务...");
throw new RuntimeException("任务失败");
});
CompletableFuture<String> whenCompleteError = errorTask.whenComplete((result, exception) -> {
if (exception != null) {
System.out.println(" whenComplete - 捕获异常: " + exception.getMessage());
System.out.println(" 记录错误日志...");
} else {
System.out.println(" whenComplete - 任务完成: " + result);
}
});
try {
whenCompleteError.get();
} catch (ExecutionException e) {
System.out.println(" whenComplete 异常依然会抛出: " + e.getCause().getMessage());
}
System.out.println();
// 8. handle vs whenComplete 对比示例
System.out.println("8. handle vs whenComplete 对比");
CompletableFuture<String> originalFuture = CompletableFuture.supplyAsync(() -> {
System.out.println(" 原始任务执行...");
throw new RuntimeException("原始异常");
});
// handle 可以恢复异常
CompletableFuture<String> handleResult = originalFuture.handle((result, ex) -> {
System.out.println(" handle: 异常恢复处理");
return ex != null ? "handle恢复值" : result;
});
// whenComplete 不能恢复异常,只能观察
CompletableFuture<String> whenCompleteResult = originalFuture.whenComplete((result, ex) -> {
System.out.println(" whenComplete: 只能观察,不能恢复");
});
System.out.println(" handle 结果: " + handleResult.get());
try {
whenCompleteResult.get();
} catch (ExecutionException e) {
System.out.println(" whenComplete 异常依然存在: " + e.getCause().getMessage());
}
System.out.println("\n=== 方法总结 ===");
System.out.println("handle: 可以处理异常并恢复,返回新结果");
System.out.println("whenComplete: 只能观察结果和异常,不能改变结果");
}
}
🔗 高级组合方法
等待条件分类
| 等待条件 | 有输出 | 无输出 | 不关心结果 |
|---|---|---|---|
| 两个都完成 | thenCombine | thenAcceptBoth | runAfterBoth |
| 任意一个完成 | applyToEither | acceptEither | runAfterEither |
| 多个任务 | - | allOf(全部) / anyOf(任意) | - |
1. 等待两个都完成 (Both)
thenCombine - 组合两个结果
CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> "用户信息");
CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> "订单信息");
CompletableFuture<String> combined = future1.thenCombine(future2,
(user, order) -> user + " + " + order
);
thenAcceptBoth - 消费两个结果
future1.thenAcceptBoth(future2, (user, order) -> {
System.out.println("处理: " + user + " 和 " + order);
// 发送邮件、记录日志等
});
runAfterBoth - 两个完成后执行
future1.runAfterBoth(future2, () -> {
System.out.println("两个任务都完成了");
// 清理资源、发送通知等
});
2. 等待任意一个完成 (Either)
applyToEither - 使用最快的结果
CompletableFuture<String> cache = CompletableFuture.supplyAsync(() -> "缓存数据");
CompletableFuture<String> db = CompletableFuture.supplyAsync(() -> "数据库数据");
CompletableFuture<String> fastest = cache.applyToEither(db,
result -> "使用: " + result
);
acceptEither - 消费最快的结果
server1.acceptEither(server2, result -> {
System.out.println("最快响应: " + result);
});
runAfterEither - 任意一个完成后执行
monitor1.runAfterEither(monitor2, () -> {
System.out.println("检测到异常,启动应急预案");
});
3. 处理多个任务
allOf - 等待所有完成
CompletableFuture<String> task1 = CompletableFuture.supplyAsync(() -> "任务1");
CompletableFuture<String> task2 = CompletableFuture.supplyAsync(() -> "任务2");
CompletableFuture<String> task3 = CompletableFuture.supplyAsync(() -> "任务3");
CompletableFuture<Void> allTasks = CompletableFuture.allOf(task1, task2, task3);
allTasks.get(); // 等待所有完成
// 获取所有结果
String result1 = task1.get();
String result2 = task2.get();
String result3 = task3.get();
anyOf - 等待任意一个完成
CompletableFuture<Object> fastest = CompletableFuture.anyOf(
service1, service2, service3
);
System.out.println("最快结果: " + fastest.get());
▶️ Demo - 高级
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
public class CompletableFutureAdvancedDemo {
public static void main(String[] args) throws ExecutionException, InterruptedException {
System.out.println("=== CompletableFuture 高级组合方法详解 ===\n");
// ========== 等待两个任务都完成的方法 ==========
// 1. thenCombine - 组合两个任务的结果(有输入,有输出)
System.out.println("1. thenCombine - 组合两个任务的结果");
CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> {
sleep(1000);
System.out.println(" 任务1完成: 获取用户信息");
return "用户:张三";
});
CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> {
sleep(800);
System.out.println(" 任务2完成: 获取订单信息");
return "订单:12345";
});
CompletableFuture<String> combinedResult = future1.thenCombine(future2, (user, order) -> {
System.out.println(" 组合结果: " + user + " + " + order);
return user + " 的 " + order;
});
System.out.println(" thenCombine 结果: " + combinedResult.get());
System.out.println();
// 2. thenAcceptBoth - 消费两个任务的结果(有输入,无输出)
System.out.println("2. thenAcceptBoth - 消费两个任务的结果");
CompletableFuture<String> task1 = CompletableFuture.supplyAsync(() -> {
sleep(500);
System.out.println(" 任务1: 生成报告");
return "销售报告";
});
CompletableFuture<String> task2 = CompletableFuture.supplyAsync(() -> {
sleep(600);
System.out.println(" 任务2: 生成图表");
return "数据图表";
});
CompletableFuture<Void> acceptBothResult = task1.thenAcceptBoth(task2, (report, chart) -> {
System.out.println(" 处理两个结果: " + report + " 和 " + chart);
System.out.println(" 发送邮件通知...");
});
acceptBothResult.get();
System.out.println(" thenAcceptBoth 完成");
System.out.println();
// 3. runAfterBoth - 两个任务都完成后执行(无输入,无输出)
System.out.println("3. runAfterBoth - 两个任务都完成后执行");
CompletableFuture<String> job1 = CompletableFuture.supplyAsync(() -> {
sleep(400);
System.out.println(" 工作1: 数据备份完成");
return "备份完成";
});
CompletableFuture<String> job2 = CompletableFuture.supplyAsync(() -> {
sleep(300);
System.out.println(" 工作2: 日志清理完成");
return "清理完成";
});
CompletableFuture<Void> runAfterBothResult = job1.runAfterBoth(job2, () -> {
System.out.println(" 两个维护任务都完成,发送完成通知");
});
runAfterBothResult.get();
System.out.println(" runAfterBoth 完成");
System.out.println();
// ========== 等待任意一个任务完成的方法 ==========
// 4. applyToEither - 使用最先完成的任务结果(有输入,有输出)
System.out.println("4. applyToEither - 使用最先完成的任务结果");
CompletableFuture<String> slowTask = CompletableFuture.supplyAsync(() -> {
sleep(1000);
System.out.println(" 慢任务: 从数据库查询");
return "数据库结果";
});
CompletableFuture<String> fastTask = CompletableFuture.supplyAsync(() -> {
sleep(300);
System.out.println(" 快任务: 从缓存查询");
return "缓存结果";
});
CompletableFuture<String> eitherResult = slowTask.applyToEither(fastTask, result -> {
System.out.println(" 使用最快的结果: " + result);
return "处理后的" + result;
});
System.out.println(" applyToEither 结果: " + eitherResult.get());
System.out.println();
// 5. acceptEither - 消费最先完成的任务结果(有输入,无输出)
System.out.println("5. acceptEither - 消费最先完成的任务结果");
CompletableFuture<String> server1 = CompletableFuture.supplyAsync(() -> {
sleep(600);
System.out.println(" 服务器1响应");
return "服务器1数据";
});
CompletableFuture<String> server2 = CompletableFuture.supplyAsync(() -> {
sleep(400);
System.out.println(" 服务器2响应");
return "服务器2数据";
});
CompletableFuture<Void> acceptEitherResult = server1.acceptEither(server2, result -> {
System.out.println(" 接收到最快响应: " + result);
System.out.println(" 开始处理数据...");
});
acceptEitherResult.get();
System.out.println(" acceptEither 完成");
System.out.println();
// 6. runAfterEither - 任意一个任务完成后执行(无输入,无输出)
System.out.println("6. runAfterEither - 任意一个任务完成后执行");
CompletableFuture<String> monitor1 = CompletableFuture.supplyAsync(() -> {
sleep(500);
System.out.println(" 监控1: 检测到异常");
return "异常报告1";
});
CompletableFuture<String> monitor2 = CompletableFuture.supplyAsync(() -> {
sleep(700);
System.out.println(" 监控2: 检测到异常");
return "异常报告2";
});
CompletableFuture<Void> runAfterEitherResult = monitor1.runAfterEither(monitor2, () -> {
System.out.println(" 任意监控检测到异常,立即启动应急预案");
});
runAfterEitherResult.get();
System.out.println(" runAfterEither 完成");
System.out.println();
// ========== 处理多个任务的静态方法 ==========
// 7. allOf - 等待所有任务完成
System.out.println("7. allOf - 等待所有任务完成");
CompletableFuture<String> task_a = CompletableFuture.supplyAsync(() -> {
sleep(300);
System.out.println(" 任务A完成");
return "结果A";
});
CompletableFuture<String> task_b = CompletableFuture.supplyAsync(() -> {
sleep(500);
System.out.println(" 任务B完成");
return "结果B";
});
CompletableFuture<String> task_c = CompletableFuture.supplyAsync(() -> {
sleep(200);
System.out.println(" 任务C完成");
return "结果C";
});
CompletableFuture<Void> allOfResult = CompletableFuture.allOf(task_a, task_b, task_c);
allOfResult.get(); // 等待所有任务完成
// 获取所有结果
System.out.println(" 所有任务完成,结果: " +
task_a.get() + ", " + task_b.get() + ", " + task_c.get());
System.out.println();
// 8. anyOf - 等待任意一个任务完成
System.out.println("8. anyOf - 等待任意一个任务完成");
CompletableFuture<String> service_x = CompletableFuture.supplyAsync(() -> {
sleep(800);
System.out.println(" 服务X响应");
return "服务X结果";
});
CompletableFuture<String> service_y = CompletableFuture.supplyAsync(() -> {
sleep(400);
System.out.println(" 服务Y响应");
return "服务Y结果";
});
CompletableFuture<String> service_z = CompletableFuture.supplyAsync(() -> {
sleep(600);
System.out.println(" 服务Z响应");
return "服务Z结果";
});
CompletableFuture<Object> anyOfResult = CompletableFuture.anyOf(service_x, service_y, service_z);
System.out.println(" 最快响应的结果: " + anyOfResult.get());
System.out.println();
// 综合示例:实际业务场景
System.out.println("9. 综合示例 - 电商下单流程");
// 并行执行多个检查
CompletableFuture<Boolean> stockCheck = CompletableFuture.supplyAsync(() -> {
sleep(300);
System.out.println(" 库存检查完成");
return true;
});
CompletableFuture<Boolean> priceCheck = CompletableFuture.supplyAsync(() -> {
sleep(200);
System.out.println(" 价格计算完成");
return true;
});
CompletableFuture<Boolean> userCheck = CompletableFuture.supplyAsync(() -> {
sleep(400);
System.out.println(" 用户验证完成");
return true;
});
// 等待所有检查完成
CompletableFuture<Void> allChecks = CompletableFuture.allOf(stockCheck, priceCheck, userCheck);
CompletableFuture<String> orderResult = allChecks.thenApply(v -> {
try {
if (stockCheck.get() && priceCheck.get() && userCheck.get()) {
return "订单创建成功";
} else {
return "订单创建失败";
}
} catch (Exception e) {
return "订单处理异常";
}
});
System.out.println(" " + orderResult.get());
System.out.println("\n=== 方法总结 ===");
System.out.println("等待两个都完成: thenCombine(有输出) > thenAcceptBoth(无输出) > runAfterBoth(不关心结果)");
System.out.println("等待任意一个完成: applyToEither(有输出) > acceptEither(无输出) > runAfterEither(不关心结果)");
System.out.println("处理多个任务: allOf(等待全部) vs anyOf(等待任意一个)");
}
private static void sleep(int millis) {
try {
Thread.sleep(millis);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
💼 实际应用场景
1. 电商下单流程
// 并行执行多个检查
CompletableFuture<Boolean> stockCheck = CompletableFuture.supplyAsync(() ->
checkStock(productId)
);
CompletableFuture<Boolean> priceCheck = CompletableFuture.supplyAsync(() ->
calculatePrice(productId)
);
CompletableFuture<Boolean> userCheck = CompletableFuture.supplyAsync(() ->
validateUser(userId)
);
// 等待所有检查完成
CompletableFuture<String> orderResult = CompletableFuture
.allOf(stockCheck, priceCheck, userCheck)
.thenApply(v -> {
if (stockCheck.join() && priceCheck.join() && userCheck.join()) {
return createOrder();
} else {
return "订单创建失败";
}
});
2. 缓存降级策略
CompletableFuture<String> cacheResult = CompletableFuture.supplyAsync(() ->
getFromCache(key)
);
CompletableFuture<String> dbResult = CompletableFuture.supplyAsync(() ->
getFromDatabase(key)
);
// 谁快用谁,实现缓存降级
CompletableFuture<String> result = cacheResult.applyToEither(dbResult,
data -> processData(data)
);
3. 微服务聚合
CompletableFuture<UserInfo> userFuture = CompletableFuture.supplyAsync(() ->
userService.getUser(userId)
);
CompletableFuture<List<Order>> orderFuture = CompletableFuture.supplyAsync(() ->
orderService.getOrders(userId)
);
CompletableFuture<UserProfile> profileFuture = userFuture.thenCombine(orderFuture,
(user, orders) -> new UserProfile(user, orders)
);
🎯 最佳实践
1. 异常处理
// ✅ 好的做法 - 使用 handle 进行异常恢复
CompletableFuture<String> safeFuture = riskyOperation()
.handle((result, ex) -> {
if (ex != null) {
log.error("操作失败", ex);
return "默认值";
}
return result;
});
// ❌ 避免 - 不处理异常
CompletableFuture<String> unsafeFuture = riskyOperation(); // 可能抛异常
2. 自定义线程池
// ✅ 推荐 - 使用自定义线程池
ExecutorService customExecutor = Executors.newFixedThreadPool(10);
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
return heavyComputation();
}, customExecutor);
// 记得关闭线程池
customExecutor.shutdown();
3. 避免阻塞
// ❌ 避免 - 在异步任务中调用阻塞方法
CompletableFuture.supplyAsync(() -> {
return anotherFuture.get(); // 阻塞!
});
// ✅ 推荐 - 使用 thenCompose 组合
CompletableFuture.supplyAsync(() -> {
return "first";
}).thenCompose(result -> {
return anotherAsyncOperation(result);
});
4. 超时处理
// ✅ 设置超时
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
return slowOperation();
}).orTimeout(5, TimeUnit.SECONDS)
.handle((result, ex) -> {
if (ex instanceof TimeoutException) {
return "操作超时";
}
return result;
});
📝 方法速查表
创建方法
runAsync(Runnable)- 无返回值异步任务supplyAsync(Supplier<T>)- 有返回值异步任务
转换方法
thenApply(Function)- 转换结果thenCompose(Function)- 组合异步操作
消费方法
thenAccept(Consumer)- 消费结果thenRun(Runnable)- 执行后续操作
异常处理
handle(BiFunction)- 处理结果和异常,可恢复whenComplete(BiConsumer)- 观察结果和异常,不可恢复
组合方法
thenCombine/thenAcceptBoth/runAfterBoth- 等待两个都完成applyToEither/acceptEither/runAfterEither- 等待任意一个完成allOf- 等待所有完成anyOf- 等待任意一个完成
获取结果
get()- 阻塞获取,抛受检异常join()- 阻塞获取,抛运行时异常
🎓 总结
CompletableFuture 是 Java 异步编程的强大工具,它提供了:
- 简洁的 API - 链式调用,代码更优雅
- 丰富的组合能力 - 可以灵活组合多个异步任务
- 内置异常处理 - handle/whenComplete 处理异常
- 高性能 - 基于 ForkJoinPool,充分利用多核
掌握 CompletableFuture 可以让你写出更高效、更优雅的异步代码!