Java CompletableFuture 完整案例详解
基础概念
CompletableFuture 是 Java 8 引入的异步编程工具,实现了 Future 和 CompletionStage 接口,支持函数式编程风格。

基础用法案例
1 创建 CompletableFuture
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
public class BasicExample {
public static void main(String[] args) throws ExecutionException, InterruptedException {
// 1. 使用 supplyAsync 创建异步任务(有返回值)
CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> {
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "Hello from async task";
});
// 2. 使用 runAsync 创建异步任务(无返回值)
CompletableFuture<Void> future2 = CompletableFuture.runAsync(() -> {
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Running async task without return value");
});
// 获取结果
System.out.println("Future1 result: " + future1.get());
future2.get();
// 3. 使用 completedFuture 创建已完成的任务
CompletableFuture<String> completedFuture = CompletableFuture.completedFuture("Already completed");
System.out.println("Completed future: " + completedFuture.get());
}
}
异步任务编排案例
1 任务串联 (thenApply, thenAccept, thenRun)
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
public class ChainExample {
public static void main(String[] args) throws Exception {
// thenApply: 对结果进行转换
CompletableFuture<String> future = CompletableFuture
.supplyAsync(() -> "Hello")
.thenApply(s -> s + " World") // 第一个转换
.thenApply(String::toUpperCase); // 第二个转换
System.out.println("thenApply result: " + future.get());
// thenAccept: 消费结果(无返回值)
CompletableFuture.supplyAsync(() -> "Data")
.thenAccept(data -> System.out.println("Processing: " + data));
// thenRun: 纯粹执行任务(不关心结果)
CompletableFuture.supplyAsync(() -> "Source")
.thenRun(() -> System.out.println("Task completed"));
// 等待所有任务完成
TimeUnit.SECONDS.sleep(2);
}
}
2 组合多个 CompletableFuture
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
public class CombineExample {
public static void main(String[] args) throws Exception {
// thenCompose: 将两个 CompletableFuture 串联
CompletableFuture<String> composedFuture = getUserInfo()
.thenCompose(user -> getOrders(user));
System.out.println("Composed result: " + composedFuture.get());
// thenCombine: 并行执行两个任务并组合结果
CompletableFuture<String> orderFuture = CompletableFuture
.supplyAsync(() -> "订单信息")
.thenCombine(
CompletableFuture.supplyAsync(() -> "用户信息"),
(order, user) -> order + " + " + user
);
System.out.println("Combined result: " + orderFuture.get());
// thenAcceptBoth: 并行执行两个任务,消费两个结果
CompletableFuture.supplyAsync(() -> "Order1")
.thenAcceptBoth(
CompletableFuture.supplyAsync(() -> "User1"),
(order, user) -> System.out.println(order + " belongs to " + user)
);
TimeUnit.SECONDS.sleep(2);
}
private static CompletableFuture<String> getUserInfo() {
return CompletableFuture.supplyAsync(() -> {
sleep(1);
return "user123";
});
}
private static CompletableFuture<String> getOrders(String userId) {
return CompletableFuture.supplyAsync(() -> {
sleep(1);
return "用户 " + userId + " 的订单列表";
});
}
private static void sleep(int seconds) {
try {
TimeUnit.SECONDS.sleep(seconds);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
实际业务场景案例
1 异步获取多个接口数据
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
public class RealWorldExample {
public static void main(String[] args) throws Exception {
// 模拟从多个服务获取数据
CompletableFuture<String> userInfo = getUserInfoAsync();
CompletableFuture<List<String>> userOrders = getUserOrdersAsync();
CompletableFuture<Double> userBalance = getUserBalanceAsync();
// 等待所有任务完成
CompletableFuture<Void> allOf = CompletableFuture.allOf(userInfo, userOrders, userBalance);
allOf.get(); // 等待所有完成
// 获取所有结果
System.out.println("用户信息: " + userInfo.get());
System.out.println("用户订单: " + userOrders.get());
System.out.println("用户余额: " + userBalance.get());
// 使用 anyOf 等待任意一个完成
CompletableFuture<Object> anyResult = CompletableFuture.anyOf(userInfo, userOrders, userBalance);
System.out.println("最先完成的任务: " + anyResult.get());
}
private static CompletableFuture<String> getUserInfoAsync() {
return CompletableFuture.supplyAsync(() -> {
sleep(2);
return "张三, 30岁, 北京";
});
}
private static CompletableFuture<List<String>> getUserOrdersAsync() {
return CompletableFuture.supplyAsync(() -> {
sleep(1);
return Arrays.asList("订单1:手机", "订单2:电脑", "订单3:耳机");
});
}
private static CompletableFuture<Double> getUserBalanceAsync() {
return CompletableFuture.supplyAsync(() -> {
sleep(3);
return 9999.99;
});
}
private static void sleep(int seconds) {
try {
TimeUnit.SECONDS.sleep(seconds);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
2 批量异步任务处理
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
public class BatchProcessExample {
public static void main(String[] args) throws Exception {
List<Integer> userIds = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
// 并行处理所有用户
List<CompletableFuture<UserData>> futures = userIds.stream()
.map(id -> processUserAsync(id))
.collect(Collectors.toList());
// 等待所有任务完成并收集结果
CompletableFuture<List<UserData>> allResults = CompletableFuture
.allOf(futures.toArray(new CompletableFuture[0]))
.thenApply(v -> futures.stream()
.map(CompletableFuture::join)
.collect(Collectors.toList()));
List<UserData> results = allResults.get();
results.forEach(System.out::println);
}
private static CompletableFuture<UserData> processUserAsync(Integer userId) {
return CompletableFuture.supplyAsync(() -> {
try {
TimeUnit.MILLISECONDS.sleep(100); // 模拟耗时操作
} catch (InterruptedException e) {
e.printStackTrace();
}
return new UserData(userId, "User_" + userId, Math.random() * 100);
});
}
static class UserData {
private Integer id;
private String name;
private double score;
public UserData(Integer id, String name, double score) {
this.id = id;
this.name = name;
this.score = score;
}
@Override
public String toString() {
return String.format("User{id=%d, name='%s', score=%.2f}", id, name, score);
}
}
}
异常处理案例
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
public class ExceptionExample {
public static void main(String[] args) throws Exception {
// 1. exceptionally: 异常时提供默认值
CompletableFuture<String> future1 = CompletableFuture
.supplyAsync(() -> {
if (Math.random() > 0.5) {
throw new RuntimeException("模拟异常1");
}
return "成功结果1";
})
.exceptionally(ex -> {
System.out.println("处理异常1: " + ex.getMessage());
return "默认值1";
});
System.out.println("Future1 result: " + future1.get());
// 2. handle: 无论成功或失败都会执行
CompletableFuture<String> future2 = CompletableFuture
.supplyAsync(() -> {
if (Math.random() > 0.5) {
throw new RuntimeException("模拟异常2");
}
return "成功结果2";
})
.handle((result, ex) -> {
if (ex != null) {
System.out.println("捕获异常2: " + ex.getMessage());
return "错误恢复2";
}
return "成功结果2";
});
System.out.println("Future2 result: " + future2.get());
// 3. 使用 whenComplete 处理完成事件(不改变结果)
CompletableFuture.supplyAsync(() -> "测试数据")
.whenComplete((result, ex) -> {
if (ex == null) {
System.out.println("任务完成,结果: " + result);
} else {
System.out.println("任务失败: " + ex.getMessage());
}
})
.join();
}
}
超时和取消控制
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
public class TimeoutExample {
public static void main(String[] args) {
// 1. 设置超时时间
CompletableFuture<String> future1 = CompletableFuture
.supplyAsync(() -> {
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "长时间任务结果";
})
.completeOnTimeout("超时默认值", 2, TimeUnit.SECONDS);
// 2. 或抛出 TimeoutException
CompletableFuture<String> future2 = CompletableFuture
.supplyAsync(() -> {
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "长时间任务结果2";
})
.orTimeout(1, TimeUnit.SECONDS);
try {
// 获取结果
System.out.println("Future1: " + future1.get(3, TimeUnit.SECONDS));
// 这个会抛出 TimeoutException
System.out.println("Future2: " + future2.get());
} catch (ExecutionException | InterruptedException | TimeoutException e) {
System.out.println("Future2 超时了: " + e.getMessage());
}
// 手动取消任务
CompletableFuture<String> future3 = CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
return "可取消的任务";
});
// 取消任务
future3.cancel(true);
System.out.println("Future3 已取消: " + future3.isCancelled());
}
}
自定义线程池案例
import java.util.concurrent.*;
public class CustomExecutorExample {
public static void main(String[] args) throws Exception {
// 创建自定义线程池
ThreadPoolExecutor executor = new ThreadPoolExecutor(
4, // 核心线程数
8, // 最大线程数
60L, // 空闲线程存活时间
TimeUnit.SECONDS, // 时间单位
new ArrayBlockingQueue<>(100), // 任务队列
new ThreadPoolExecutor.CallerRunsPolicy() // 拒绝策略
);
// 1. 使用自定义线程池
CompletableFuture<String> future = CompletableFuture
.supplyAsync(() -> {
System.out.println("当前线程: " + Thread.currentThread().getName());
return "自定义线程池任务";
}, executor);
System.out.println("结果: " + future.get());
// 2. 多个任务共享同一个线程池
CompletableFuture<Integer> task1 = CompletableFuture
.supplyAsync(() -> {
try { Thread.sleep(1000); } catch (InterruptedException e) {}
return 5;
}, executor);
CompletableFuture<Integer> task2 = CompletableFuture
.supplyAsync(() -> {
try { Thread.sleep(500); } catch (InterruptedException e) {}
return 3;
}, executor);
// 组合两个任务
CompletableFuture<Integer> combined = task1.thenCombine(task2, (x, y) -> x * y);
System.out.println("组合结果: " + combined.get());
// 关闭线程池
executor.shutdown();
}
}
实际综合应用示例
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
public class OrderProcessingSystem {
public static void main(String[] args) throws Exception {
OrderProcessingSystem system = new OrderProcessingSystem();
// 创建订单并处理
Order order = system.processOrder("ORD-001", "user123")
.get(); // 同步等待最终结果
System.out.println("订单处理完成:");
System.out.println("订单号: " + order.getOrderId());
System.out.println("用户: " + order.getUser());
System.out.println("商品: " + order.getProducts());
System.out.println("总价: " + order.getTotalPrice());
System.out.println("状态: " + order.getStatus());
}
public CompletableFuture<Order> processOrder(String orderId, String userId) {
// 1. 获取用户信息
CompletableFuture<String> userInfoFuture = CompletableFuture
.supplyAsync(() -> getMockUserInfo(userId));
// 2. 获取库存信息
CompletableFuture<Boolean> stockCheckFuture = CompletableFuture
.supplyAsync(() -> checkStock(orderId));
// 3. 计算价格
CompletableFuture<Double> priceFuture = CompletableFuture
.supplyAsync(() -> calculatePrice(orderId));
// 并行执行所有任务,然后组合结果
return userInfoFuture
.thenCombine(stockCheckFuture, (user, inStock) -> {
if (!inStock) {
throw new RuntimeException("库存不足");
}
return user;
})
.thenCombine(priceFuture, (user, price) -> {
// 创建订单
Order order = new Order(orderId, user);
order.setTotalPrice(price);
order.setStatus("CONFIRMED");
return order;
})
.thenApply(order -> {
// 模拟其他处理
order.setStatus("PROCESSING");
return order;
})
.exceptionally(ex -> {
System.out.println("订单处理失败: " + ex.getMessage());
Order failedOrder = new Order(orderId, "Unknown");
failedOrder.setStatus("FAILED");
return failedOrder;
});
}
private String getMockUserInfo(String userId) {
try {
TimeUnit.MILLISECONDS.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "用户: " + userId + ", 等级: VIP";
}
private Boolean checkStock(String orderId) {
try {
TimeUnit.MILLISECONDS.sleep(150);
} catch (InterruptedException e) {
e.printStackTrace();
}
return true; // 简化模拟
}
private Double calculatePrice(String orderId) {
try {
TimeUnit.MILLISECONDS.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
return 2999.00;
}
static class Order {
private String orderId;
private String user;
private double totalPrice;
private String status;
private List<String> products = new ArrayList<>();
public Order(String orderId, String user) {
this.orderId = orderId;
this.user = user;
this.products.add("iPhone 15");
this.products.add("AirPods Pro");
}
// Getters and Setters
public String getOrderId() { return orderId; }
public String getUser() { return user; }
public double getTotalPrice() { return totalPrice; }
public void setTotalPrice(double totalPrice) { this.totalPrice = totalPrice; }
public String getStatus() { return status; }
public void setStatus(String status) { this.status = status; }
public List<String> getProducts() { return products; }
}
}
最佳实践建议
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class BestPractices {
private final ExecutorService executor = Executors.newFixedThreadPool(10);
public void bestPracticesDemo() {
// 1. 始终使用自定义线程池,避免使用公共ForkJoinPool
CompletableFuture<String> future = CompletableFuture
.supplyAsync(() -> "任务", executor);
// 2. 避免阻塞,使用异步方法
future.thenAcceptAsync(result -> {
// 异步处理结果
}, executor);
// 3. 正确处理异常
future.exceptionally(throwable -> {
System.err.println("处理失败: " + throwable);
return "";
});
// 4. 设置合理的超时
future.completeOnTimeout("timeout", 5, java.util.concurrent.TimeUnit.SECONDS);
// 5. 使用 join() 而不是 get() 避免检查异常
try {
String result = future.join();
} catch (Exception e) {
e.printStackTrace();
}
// 6. 资源管理:确保关闭线程池
executor.shutdown();
}
}
这些案例覆盖了 CompletableFuture 的主要功能和应用场景,可根据实际需求选择合适的模式使用。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播