之前已经有了一篇介绍CompletableFuture使用的文章,但是感觉例子不够清晰,重新组织了一版:
一、基础入门篇 🎯
1.1 创建 CompletableFuture
java
public class CompletableFutureBasic {
/**
* 1. 创建已完成的 CompletableFuture
*/
public void createCompletedFuture() {
// 直接创建已完成并带有结果值的 Future
CompletableFuture<String> completedFuture = CompletableFuture.completedFuture("Hello World");
// 获取结果(立即返回,不会阻塞)
try {
String result = completedFuture.get();
System.out.println("已完成 Future 结果: " + result);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 2. 使用 runAsync 执行无返回值的异步任务
* 适用于不需要返回结果的场景
*/
public void runAsyncExample() {
CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
// 模拟耗时操作
try {
Thread.sleep(1000);
System.out.println("异步任务执行完成,线程: " + Thread.currentThread().getName());
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
});
// 等待任务完成
future.join(); // join() 不会抛出受检异常
System.out.println("runAsync 任务完成");
}
/**
* 3. 使用 supplyAsync 执行有返回值的异步任务
* 适用于需要返回计算结果的场景
*/
public void supplyAsyncExample() {
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
// 模拟数据计算
try {
Thread.sleep(2000);
System.out.println("数据计算完成,线程: " + Thread.currentThread().getName());
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return "任务被中断";
}
return "计算结果: 42";
});
// 获取计算结果
try {
String result = future.get(3, TimeUnit.SECONDS); // 设置超时时间
System.out.println("supplyAsync 结果: " + result);
} catch (TimeoutException e) {
System.out.println("任务执行超时");
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 4. 使用自定义线程池
* 默认使用 ForkJoinPool.commonPool(),但可以指定自定义线程池
*/
public void customThreadPoolExample() {
// 创建自定义线程池
ExecutorService customExecutor = Executors.newFixedThreadPool(3,
new ThreadFactory() {
private AtomicInteger counter = new AtomicInteger(1);
@Override
public Thread newThread(Runnable r) {
return new Thread(r, "custom-pool-" + counter.getAndIncrement());
}
});
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
System.out.println("使用自定义线程池执行,线程: " + Thread.currentThread().getName());
return "自定义线程池结果";
}, customExecutor);
String result = future.join();
System.out.println("结果: " + result);
// 关闭线程池
customExecutor.shutdown();
}
}
1.2 结果处理基础
java
public class ResultHandlingBasic {
/**
* 1. thenApply - 转换结果
* 当前阶段完成后,将结果转换为另一种类型
*/
public void thenApplyExample() {
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
System.out.println("第一阶段: 获取用户ID");
return "user123";
}).thenApply(userId -> {
System.out.println("第二阶段: 根据用户ID查询用户信息");
return "用户信息: " + userId;
}).thenApply(userInfo -> {
System.out.println("第三阶段: 格式化用户信息");
return userInfo + " [已格式化]";
});
String result = future.join();
System.out.println("最终结果: " + result);
}
/**
* 2. thenAccept - 消费结果
* 接收前一阶段的结果并进行消费,不返回新值
*/
public void thenAcceptExample() {
CompletableFuture<Void> future = CompletableFuture.supplyAsync(() -> {
System.out.println("查询订单数据");
return "订单数据";
}).thenAccept(orderData -> {
System.out.println("处理订单数据: " + orderData);
// 这里可以进行数据保存、发送消息等操作
});
future.join();
System.out.println("订单处理完成");
}
/**
* 3. thenRun - 执行后续操作
* 不关心前一阶段的结果,只在前一阶段完成后执行操作
*/
public void thenRunExample() {
CompletableFuture<Void> future = CompletableFuture.supplyAsync(() -> {
System.out.println("执行数据清理操作");
return "清理结果";
}).thenRun(() -> {
System.out.println("数据清理完成,发送通知");
// 不依赖清理结果,只是执行后续操作
});
future.join();
System.out.println("整个流程完成");
}
/**
* 4. thenApply vs thenApplyAsync 区别
* thenApply: 默认在同一线程执行
* thenApplyAsync: 在另一个线程执行
*/
public void applyVsApplyAsync() {
CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> {
System.out.println("supplyAsync 线程: " + Thread.currentThread().getName());
return "初始数据";
}).thenApply(data -> {
System.out.println("thenApply 线程: " + Thread.currentThread().getName());
return data + " -> 同步转换";
});
CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> {
System.out.println("supplyAsync 线程: " + Thread.currentThread().getName());
return "初始数据";
}).thenApplyAsync(data -> {
System.out.println("thenApplyAsync 线程: " + Thread.currentThread().getName());
return data + " -> 异步转换";
});
System.out.println("同步结果: " + future1.join());
System.out.println("异步结果: " + future2.join());
}
}
二、组合操作篇 🔄
2.1 任务链式组合
java
public class TaskChaining {
/**
* 1. thenCompose - 扁平化链式调用
* 用于一个异步操作依赖另一个异步操作的结果
*/
public void thenComposeExample() {
// 模拟用户服务
CompletableFuture<String> userFuture = CompletableFuture.supplyAsync(() -> {
System.out.println("查询用户信息");
return "user_1001";
});
// thenCompose 将两个 Future 扁平化,避免嵌套
CompletableFuture<String> resultFuture = userFuture.thenCompose(userId -> {
return CompletableFuture.supplyAsync(() -> {
System.out.println("根据用户ID查询订单: " + userId);
return "订单列表 for " + userId;
});
});
String result = resultFuture.join();
System.out.println("最终结果: " + result);
// 对比:如果不使用 thenCompose 会有嵌套
CompletableFuture<CompletableFuture<String>> nestedFuture =
userFuture.thenApply(userId ->
CompletableFuture.supplyAsync(() -> "订单列表 for " + userId)
);
}
/**
* 2. thenCombine - 合并两个独立任务的结果
* 两个任务并行执行,完成后合并它们的结果
*/
public void thenCombineExample() {
CompletableFuture<String> userFuture = CompletableFuture.supplyAsync(() -> {
System.out.println("并行任务1: 查询用户信息");
try { Thread.sleep(1000); } catch (InterruptedException e) { /* ignore */ }
return "用户A";
});
CompletableFuture<String> productFuture = CompletableFuture.supplyAsync(() -> {
System.out.println("并行任务2: 查询商品信息");
try { Thread.sleep(800); } catch (InterruptedException e) { /* ignore */ }
return "商品B";
});
// 合并两个任务的结果
CompletableFuture<String> combinedFuture = userFuture.thenCombine(productFuture,
(user, product) -> {
System.out.println("合并用户和商品信息");
return user + " 购买了 " + product;
});
String result = combinedFuture.join();
System.out.println("合并结果: " + result);
}
/**
* 3. thenAcceptBoth - 消费两个任务的结果
* 类似 thenCombine,但只消费不返回新值
*/
public void thenAcceptBothExample() {
CompletableFuture<Integer> stockFuture = CompletableFuture.supplyAsync(() -> {
System.out.println("查询库存");
return 100;
});
CompletableFuture<Double> priceFuture = CompletableFuture.supplyAsync(() -> {
System.out.println("查询价格");
return 299.99;
});
CompletableFuture<Void> resultFuture = stockFuture.thenAcceptBoth(priceFuture,
(stock, price) -> {
System.out.println("库存: " + stock + ", 价格: " + price);
System.out.println("总价值: " + (stock * price));
});
resultFuture.join();
System.out.println("消费完成");
}
/**
* 4. runAfterBoth - 两个任务完成后执行
* 不关心任务结果,只关心完成状态
*/
public void runAfterBothExample() {
CompletableFuture<Void> task1 = CompletableFuture.runAsync(() -> {
System.out.println("任务1: 数据备份");
try { Thread.sleep(1000); } catch (InterruptedException e) { /* ignore */ }
});
CompletableFuture<Void> task2 = CompletableFuture.runAsync(() -> {
System.out.println("任务2: 日志清理");
try { Thread.sleep(800); } catch (InterruptedException e) { /* ignore */ }
});
CompletableFuture<Void> result = task1.runAfterBoth(task2, () -> {
System.out.println("两个任务都完成了,开始执行后续操作");
});
result.join();
System.out.println("所有操作完成");
}
}
2.2 多任务组合
java
public class MultipleTaskCombination {
/**
* 1. allOf - 等待所有任务完成
* 适用于需要等待多个并行任务全部完成的场景
*/
public void allOfExample() {
List<CompletableFuture<String>> futures = new ArrayList<>();
// 创建多个并行任务
for (int i = 1; i <= 5; i++) {
final int taskId = i;
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
try {
// 模拟不同的执行时间
Thread.sleep(ThreadLocalRandom.current().nextInt(1000, 3000));
System.out.println("任务 " + taskId + " 完成");
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
return "任务" + taskId + "结果";
});
futures.add(future);
}
// 等待所有任务完成
CompletableFuture<Void> allFutures = CompletableFuture.allOf(
futures.toArray(new CompletableFuture[0])
);
// 所有任务完成后处理结果
CompletableFuture<List<String>> resultsFuture = allFutures.thenApply(v -> {
return futures.stream()
.map(CompletableFuture::join) // 此时所有任务已完成,join不会阻塞
.collect(Collectors.toList());
});
List<String> results = resultsFuture.join();
System.out.println("所有任务完成,结果: " + results);
}
/**
* 2. anyOf - 任意一个任务完成
* 适用于竞速场景,只需要最快的结果
*/
public void anyOfExample() {
// 模拟多个数据源查询
CompletableFuture<String> source1 = CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(1200);
System.out.println("数据源1返回");
} catch (InterruptedException e) { /* ignore */ }
return "数据源1结果";
});
CompletableFuture<String> source2 = CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(800);
System.out.println("数据源2返回");
} catch (InterruptedException e) { /* ignore */ }
return "数据源2结果";
});
CompletableFuture<String> source3 = CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(1500);
System.out.println("数据源3返回");
} catch (InterruptedException e) { /* ignore */ }
return "数据源3结果";
});
// 获取最快返回的结果
CompletableFuture<Object> fastestFuture = CompletableFuture.anyOf(source1, source2, source3);
Object fastestResult = fastestFuture.join();
System.out.println("最快返回的结果: " + fastestResult);
}
/**
* 3. 复杂组合:电商订单处理流程
*/
public void ecommerceOrderProcessing() {
// 1. 验证订单
CompletableFuture<Boolean> validationFuture = CompletableFuture.supplyAsync(() -> {
System.out.println("验证订单信息...");
try { Thread.sleep(200); } catch (InterruptedException e) { /* ignore */ }
return true;
});
// 2. 检查库存(并行)
CompletableFuture<Boolean> stockFuture = CompletableFuture.supplyAsync(() -> {
System.out.println("检查商品库存...");
try { Thread.sleep(300); } catch (InterruptedException e) { /* ignore */ }
return true;
});
// 3. 计算价格(并行)
CompletableFuture<Double> priceFuture = CompletableFuture.supplyAsync(() -> {
System.out.println("计算订单价格...");
try { Thread.sleep(250); } catch (InterruptedException e) { /* ignore */ }
return 299.99;
});
// 等待验证和库存检查都通过
CompletableFuture<Boolean> preCheckFuture = validationFuture.thenCombine(stockFuture,
(valid, inStock) -> valid && inStock);
// 所有前置条件满足后,处理订单
CompletableFuture<String> orderFuture = preCheckFuture.thenCompose(passed -> {
if (!passed) {
return CompletableFuture.completedFuture("订单验证失败");
}
return priceFuture.thenApply(price -> {
System.out.println("创建订单,价格: " + price);
return "订单创建成功,金额: " + price;
});
});
String result = orderFuture.join();
System.out.println("订单处理结果: " + result);
}
}
三、异常处理篇 ⚠️
3.1 基础异常处理
java
public class ExceptionHandling {
/**
* 1. exceptionally - 捕获异常并提供默认值
* 类似于 try-catch,在发生异常时返回备用值
*/
public void exceptionallyExample() {
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
System.out.println("开始执行可能失败的任务...");
if (Math.random() > 0.5) {
throw new RuntimeException("模拟业务异常");
}
return "成功结果";
}).exceptionally(throwable -> {
// 捕获异常,返回默认值
System.err.println("捕获到异常: " + throwable.getMessage());
return "默认结果";
});
String result = future.join();
System.out.println("最终结果: " + result);
}
/**
* 2. handle - 统一处理成功和异常情况
* 无论成功还是失败都会执行,可以转换结果或恢复
*/
public void handleExample() {
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
System.out.println("执行任务...");
if (Math.random() > 0.7) {
throw new RuntimeException("任务执行失败");
}
return "原始结果";
}).handle((result, throwable) -> {
if (throwable != null) {
// 处理异常情况
System.err.println("任务失败: " + throwable.getMessage());
return "异常恢复结果";
} else {
// 处理成功情况
System.out.println("任务成功: " + result);
return result + " -> 处理后的结果";
}
});
String result = future.join();
System.out.println("处理后的结果: " + result);
}
/**
* 3. whenComplete - 完成时回调(不改变结果)
* 类似于 finally,无论成功失败都会执行,但不改变结果
*/
public void whenCompleteExample() {
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
System.out.println("执行核心业务...");
if (Math.random() > 0.6) {
throw new RuntimeException("业务异常");
}
return "业务结果";
}).whenComplete((result, throwable) -> {
// 执行清理或日志记录操作
if (throwable != null) {
System.err.println("业务执行失败,记录日志: " + throwable.getMessage());
} else {
System.out.println("业务执行成功,结果: " + result);
}
System.out.println("执行清理操作...");
});
try {
String result = future.join();
System.out.println("最终获取的结果: " + result);
} catch (Exception e) {
System.err.println("外层捕获异常: " + e.getMessage());
}
}
}
3.2 高级异常处理模式
java
public class AdvancedExceptionHandling {
/**
* 1. 异常传播和恢复链
* 在复杂的链式调用中处理异常
*/
public void exceptionPropagationChain() {
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
System.out.println("阶段1: 数据获取");
if (Math.random() > 0.8) {
throw new RuntimeException("数据获取失败");
}
return "原始数据";
})
.thenApply(data -> {
System.out.println("阶段2: 数据转换");
if (Math.random() > 0.9) {
throw new RuntimeException("数据转换失败");
}
return data + " -> 转换后";
})
.exceptionally(throwable -> {
// 第一阶段或第二阶段异常的恢复
System.err.println("前两阶段异常,使用备用数据: " + throwable.getMessage());
return "备用数据";
})
.thenApply(data -> {
System.out.println("阶段3: 最终处理: " + data);
return data + " -> 最终结果";
})
.handle((result, throwable) -> {
// 最终的统一处理
if (throwable != null) {
return "系统异常: " + throwable.getMessage();
}
return result;
});
String result = future.join();
System.out.println("链式处理结果: " + result);
}
/**
* 2. 超时控制
* 使用 completeOnTimeout 设置超时默认值
*/
public void timeoutControlExample() {
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
try {
// 模拟长时间运行的任务
Thread.sleep(5000);
return "正常结果";
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return "中断结果";
}
})
.completeOnTimeout("超时默认值", 2, TimeUnit.SECONDS) // 2秒超时
.exceptionally(throwable -> {
System.err.println("其他异常: " + throwable.getMessage());
return "异常默认值";
});
String result = future.join();
System.out.println("超时控制结果: " + result);
}
/**
* 3. 重试机制
* 实现带重试的异步操作
*/
public void retryMechanism() {
AtomicInteger retryCount = new AtomicInteger(0);
int maxRetries = 3;
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
int currentTry = retryCount.incrementAndGet();
System.out.println("第 " + currentTry + " 次尝试...");
if (Math.random() > 0.3 && currentTry < maxRetries) {
throw new RuntimeException("模拟失败,需要重试");
}
return "成功结果(第 " + currentTry + " 次尝试)";
})
.exceptionally(throwable -> {
if (retryCount.get() < maxRetries) {
System.out.println("执行失败,进行重试...");
// 在实际项目中,这里可以重新提交任务
return "重试结果";
} else {
return "达到最大重试次数,返回默认值";
}
});
String result = future.join();
System.out.println("重试机制结果: " + result);
}
/**
* 4. 组合操作中的异常处理
* 处理多个并行任务中的异常
*/
public void exceptionInCombination() {
CompletableFuture<String> task1 = CompletableFuture.supplyAsync(() -> {
System.out.println("任务1执行");
throw new RuntimeException("任务1失败");
}).exceptionally(e -> "任务1默认结果");
CompletableFuture<String> task2 = CompletableFuture.supplyAsync(() -> {
System.out.println("任务2执行");
return "任务2成功结果";
});
// 即使 task1 失败,task2 仍然会执行
CompletableFuture<Void> combined = CompletableFuture.allOf(task1, task2)
.exceptionally(throwable -> {
System.err.println("组合任务异常: " + throwable.getMessage());
return null;
});
combined.join();
// 获取各自的结果(即使有失败)
String result1 = task1.exceptionally(e -> "获取失败").join();
String result2 = task2.exceptionally(e -> "获取失败").join();
System.out.println("任务1结果: " + result1);
System.out.println("任务2结果: " + result2);
}
}
四、高级应用篇 🚀
4.1 性能优化模式
java
public class PerformanceOptimization {
/**
* 1. 并行流水线处理
* 将大任务拆分为多个小任务并行处理
*/
public void parallelPipeline() {
// 模拟数据处理流水线
CompletableFuture<String> resultFuture = CompletableFuture.supplyAsync(() -> {
System.out.println("阶段1: 数据采集");
return "原始数据";
})
.thenApplyAsync(data -> {
System.out.println("阶段2: 数据清洗 - " + Thread.currentThread().getName());
return data + " -> 清洗后";
})
.thenApplyAsync(data -> {
System.out.println("阶段3: 数据转换 - " + Thread.currentThread().getName());
return data + " -> 转换后";
})
.thenApplyAsync(data -> {
System.out.println("阶段4: 数据聚合 - " + Thread.currentThread().getName());
return data + " -> 聚合完成";
});
String result = resultFuture.join();
System.out.println("流水线处理结果: " + result);
}
/**
* 2. 批量异步处理
* 处理大量独立任务的优化模式
*/
public void batchAsyncProcessing() {
List<Integer> dataList = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
// 为每个数据项创建异步任务
List<CompletableFuture<String>> futures = dataList.stream()
.map(item -> CompletableFuture.supplyAsync(() -> {
try {
// 模拟处理时间
Thread.sleep(100);
System.out.println("处理数据: " + item + " - " + Thread.currentThread().getName());
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
return "结果-" + item;
}))
.collect(Collectors.toList());
// 等待所有任务完成
CompletableFuture<Void> allDone = CompletableFuture.allOf(
futures.toArray(new CompletableFuture[0])
);
// 收集结果
CompletableFuture<List<String>> resultsFuture = allDone.thenApply(v ->
futures.stream()
.map(CompletableFuture::join)
.collect(Collectors.toList())
);
List<String> results = resultsFuture.join();
System.out.println("批量处理完成,结果数量: " + results.size());
System.out.println("前3个结果: " + results.subList(0, 3));
}
/**
* 3. 缓存模式
* 使用 CompletableFuture 作为缓存值,避免重复计算
*/
public class AsyncCache<K, V> {
private final ConcurrentHashMap<K, CompletableFuture<V>> cache = new ConcurrentHashMap<>();
private final Function<K, V> loader;
public AsyncCache(Function<K, V> loader) {
this.loader = loader;
}
public CompletableFuture<V> get(K key) {
return cache.computeIfAbsent(key, k ->
CompletableFuture.supplyAsync(() -> loader.apply(k))
.exceptionally(throwable -> {
// 发生异常时移除缓存
cache.remove(key);
throw new CompletionException(throwable);
})
);
}
}
public void cachePatternExample() {
AsyncCache<String, String> cache = new AsyncCache<>(key -> {
System.out.println("计算值: " + key);
try { Thread.sleep(1000); } catch (InterruptedException e) { /* ignore */ }
return key + "-value";
});
// 多次获取相同key,只会计算一次
CompletableFuture<String> future1 = cache.get("key1");
CompletableFuture<String> future2 = cache.get("key1"); // 从缓存获取
CompletableFuture.allOf(future1, future2).join();
System.out.println("future1结果: " + future1.join());
System.out.println("future2结果: " + future2.join());
System.out.println("两个future是同一个对象: " + (future1 == future2));
}
}
4.2 复杂业务场景
java
public class ComplexBusinessScenarios {
/**
* 1. 电商订单全流程处理
*/
public void ecommerceFullProcess() {
// 创建自定义线程池
ExecutorService businessExecutor = Executors.newFixedThreadPool(10);
CompletableFuture<String> orderProcess = CompletableFuture
// 阶段1: 订单验证
.supplyAsync(() -> {
System.out.println("1. 验证订单信息");
try { Thread.sleep(100); } catch (InterruptedException e) { /* ignore */ }
return "订单验证通过";
}, businessExecutor)
// 阶段2: 并行检查库存和用户信用
.thenCompose(validationResult -> {
CompletableFuture<Boolean> stockCheck = CompletableFuture.supplyAsync(() -> {
System.out.println("2.1 检查库存");
try { Thread.sleep(200); } catch (InterruptedException e) { /* ignore */ }
return true;
}, businessExecutor);
CompletableFuture<Boolean> creditCheck = CompletableFuture.supplyAsync(() -> {
System.out.println("2.2 检查用户信用");
try { Thread.sleep(150); } catch (InterruptedException e) { /* ignore */ }
return true;
}, businessExecutor);
return stockCheck.thenCombine(creditCheck, (stockOk, creditOk) ->
stockOk && creditOk ? "前置检查通过" : "前置检查失败"
);
})
// 阶段3: 扣减库存和计算价格
.thenCompose(preCheckResult -> {
if (!"前置检查通过".equals(preCheckResult)) {
return CompletableFuture.completedFuture("订单创建失败: " + preCheckResult);
}
CompletableFuture<Boolean> inventoryUpdate = CompletableFuture.supplyAsync(() -> {
System.out.println("3.1 扣减库存");
try { Thread.sleep(100); } catch (InterruptedException e) { /* ignore */ }
return true;
}, businessExecutor);
CompletableFuture<Double> priceCalculation = CompletableFuture.supplyAsync(() -> {
System.out.println("3.2 计算最终价格");
try { Thread.sleep(120); } catch (InterruptedException e) { /* ignore */ }
return 299.99;
}, businessExecutor);
return inventoryUpdate.thenCombine(priceCalculation, (updateOk, price) ->
updateOk ? "订单创建成功,价格: " + price : "库存扣减失败"
);
})
// 阶段4: 发送通知(不阻塞主流程)
.whenComplete((result, throwable) -> {
if (throwable == null) {
CompletableFuture.runAsync(() -> {
System.out.println("4. 发送订单通知: " + result);
try { Thread.sleep(50); } catch (InterruptedException e) { /* ignore */ }
}, businessExecutor);
}
})
// 异常处理
.exceptionally(throwable -> {
System.err.println("订单处理异常: " + throwable.getMessage());
return "系统异常,请稍后重试";
});
String finalResult = orderProcess.join();
System.out.println("订单处理最终结果: " + finalResult);
businessExecutor.shutdown();
}
/**
* 2. 数据同步和聚合
*/
public void dataSyncAndAggregation() {
// 模拟从多个数据源获取数据
List<CompletableFuture<Map<String, Object>>> dataSourceFutures = Arrays.asList(
CompletableFuture.supplyAsync(() -> {
System.out.println("从数据库获取用户数据");
try { Thread.sleep(300); } catch (InterruptedException e) { /* ignore */ }
Map<String, Object> userData = new HashMap<>();
userData.put("userId", 1001);
userData.put("userName", "张三");
return userData;
}),
CompletableFuture.supplyAsync(() -> {
System.out.println("从Redis获取用户缓存数据");
try { Thread.sleep(100); } catch (InterruptedException e) { /* ignore */ }
Map<String, Object> cacheData = new HashMap<>();
cacheData.put("lastLogin", "2024-01-01");
cacheData.put("loginCount", 42);
return cacheData;
}),
CompletableFuture.supplyAsync(() -> {
System.out.println("从外部API获取用户积分");
try { Thread.sleep(400); } catch (InterruptedException e) { /* ignore */ }
Map<String, Object> pointsData = new HashMap<>();
pointsData.put("points", 1500);
pointsData.put("level", "VIP");
return pointsData;
})
);
// 等待所有数据源返回并聚合数据
CompletableFuture<Map<String, Object>> aggregatedFuture =
CompletableFuture.allOf(dataSourceFutures.toArray(new CompletableFuture[0]))
.thenApply(v -> {
Map<String, Object> result = new HashMap<>();
dataSourceFutures.forEach(future -> {
try {
Map<String, Object> data = future.join();
result.putAll(data);
} catch (Exception e) {
System.err.println("数据源获取失败: " + e.getMessage());
}
});
return result;
});
Map<String, Object> aggregatedData = aggregatedFuture.join();
System.out.println("聚合后的用户数据: " + aggregatedData);
}
/**
* 3. 限流和背压控制
*/
public void rateLimitingAndBackpressure() {
// 创建限流线程池
ExecutorService limitedExecutor = Executors.newFixedThreadPool(3);
Semaphore semaphore = new Semaphore(2); // 同时最多2个任务执行
List<CompletableFuture<String>> limitedFutures = new ArrayList<>();
for (int i = 1; i <= 10; i++) {
final int taskId = i;
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
try {
semaphore.acquire(); // 获取许可
System.out.println("开始执行任务 " + taskId + ",当前并发: " +
(2 - semaphore.availablePermits()));
// 模拟任务执行
Thread.sleep(1000);
return "任务" + taskId + "完成";
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return "任务" + taskId + "中断";
} finally {
semaphore.release(); // 释放许可
System.out.println("释放任务 " + taskId + ",剩余许可: " +
semaphore.availablePermits());
}
}, limitedExecutor);
limitedFutures.add(future);
}
// 等待所有任务完成
CompletableFuture<Void> allDone = CompletableFuture.allOf(
limitedFutures.toArray(new CompletableFuture[0])
);
allDone.join();
System.out.println("所有限流任务完成");
limitedExecutor.shutdown();
}
}
五、实战案例篇 🎯
5.1 微服务调用编排
java
public class MicroserviceOrchestration {
/**
* 1. 服务调用编排:用户注册流程
*/
public CompletableFuture<UserRegisterResult> userRegisterFlow(UserRegisterRequest request) {
// 阶段1: 并行验证
CompletableFuture<Boolean> emailCheck = checkEmailAvailable(request.getEmail());
CompletableFuture<Boolean> mobileCheck = checkMobileAvailable(request.getMobile());
return emailCheck.thenCombine(mobileCheck, (emailOk, mobileOk) -> {
if (!emailOk) {
throw new BusinessException("邮箱已被注册");
}
if (!mobileOk) {
throw new BusinessException("手机号已被注册");
}
return "验证通过";
})
// 阶段2: 创建用户
.thenCompose(validation -> createUser(request))
// 阶段3: 并行初始化用户数据
.thenCompose(userId -> {
CompletableFuture<Void> initProfile = initUserProfile(userId);
CompletableFuture<Void> sendWelcome = sendWelcomeMessage(userId, request.getEmail());
CompletableFuture<Void> grantPoints = grantRegisterPoints(userId);
return CompletableFuture.allOf(initProfile, sendWelcome, grantPoints)
.thenApply(v -> userId);
})
// 阶段4: 记录注册日志(异步,不阻塞)
.whenComplete((userId, throwable) -> {
if (throwable == null) {
recordRegisterLog(userId, request.getSource()).exceptionally(e -> {
System.err.println("记录日志失败: " + e.getMessage());
return null;
});
}
})
// 构建最终结果
.handle((userId, throwable) -> {
if (throwable != null) {
return UserRegisterResult.fail(throwable.getMessage());
}
return UserRegisterResult.success(userId, "注册成功");
});
}
// 模拟服务方法
private CompletableFuture<Boolean> checkEmailAvailable(String email) {
return CompletableFuture.supplyAsync(() -> {
System.out.println("检查邮箱可用性: " + email);
try { Thread.sleep(100); } catch (InterruptedException e) { /* ignore */ }
return Math.random() > 0.1; // 90%概率可用
});
}
private CompletableFuture<Boolean> checkMobileAvailable(String mobile) {
return CompletableFuture.supplyAsync(() -> {
System.out.println("检查手机号可用性: " + mobile);
try { Thread.sleep(150); } catch (InterruptedException e) { /* ignore */ }
return Math.random() > 0.1; // 90%概率可用
});
}
private CompletableFuture<String> createUser(UserRegisterRequest request) {
return CompletableFuture.supplyAsync(() -> {
System.out.println("创建用户: " + request.getEmail());
try { Thread.sleep(200); } catch (InterruptedException e) { /* ignore */ }
return "user_" + System.currentTimeMillis();
});
}
private CompletableFuture<Void> initUserProfile(String userId) {
return CompletableFuture.runAsync(() -> {
System.out.println("初始化用户档案: " + userId);
try { Thread.sleep(100); } catch (InterruptedException e) { /* ignore */ }
});
}
private CompletableFuture<Void> sendWelcomeMessage(String userId, String email) {
return CompletableFuture.runAsync(() -> {
System.out.println("发送欢迎邮件: " + email);
try { Thread.sleep(300); } catch (InterruptedException e) { /* ignore */ }
});
}
private CompletableFuture<Void> grantRegisterPoints(String userId) {
return CompletableFuture.runAsync(() -> {
System.out.println("发放注册积分: " + userId);
try { Thread.sleep(50); } catch (InterruptedException e) { /* ignore */ }
});
}
private CompletableFuture<Void> recordRegisterLog(String userId, String source) {
return CompletableFuture.runAsync(() -> {
System.out.println("记录注册日志: " + userId + ", 来源: " + source);
try { Thread.sleep(80); } catch (InterruptedException e) { /* ignore */ }
});
}
// 数据模型
static class UserRegisterRequest {
private String email;
private String mobile;
private String source;
// getters and setters
public String getEmail() { return email; }
public String getMobile() { return mobile; }
public String getSource() { return source; }
}
static class UserRegisterResult {
private boolean success;
private String userId;
private String message;
static UserRegisterResult success(String userId, String message) {
UserRegisterResult result = new UserRegisterResult();
result.success = true;
result.userId = userId;
result.message = message;
return result;
}
static UserRegisterResult fail(String message) {
UserRegisterResult result = new UserRegisterResult();
result.success = false;
result.message = message;
return result;
}
}
static class BusinessException extends RuntimeException {
public BusinessException(String message) {
super(message);
}
}
}
5.2 性能监控和调试
java
public class PerformanceMonitoring {
/**
* 带监控的 CompletableFuture 包装器
*/
public static class MonitoredCompletableFuture<T> {
private final CompletableFuture<T> future;
private final long startTime;
private final String taskName;
public MonitoredCompletableFuture(CompletableFuture<T> future, String taskName) {
this.future = future;
this.startTime = System.currentTimeMillis();
this.taskName = taskName;
// 添加完成回调记录指标
this.future.whenComplete((result, throwable) -> {
long duration = System.currentTimeMillis() - startTime;
if (throwable != null) {
System.out.printf("⏰ 任务监控 [%s] - 失败 - 耗时: %dms - 异常: %s%n",
taskName, duration, throwable.getMessage());
} else {
System.out.printf("⏰ 任务监控 [%s] - 成功 - 耗时: %dms%n",
taskName, duration);
}
});
}
public CompletableFuture<T> getFuture() {
return future;
}
public static <T> MonitoredCompletableFuture<T> supplyAsync(
Supplier<T> supplier, String taskName) {
return new MonitoredCompletableFuture<>(
CompletableFuture.supplyAsync(supplier), taskName);
}
}
/**
* 使用监控包装器的示例
*/
public void monitoredExample() {
MonitoredCompletableFuture<String> task1 = MonitoredCompletableFuture.supplyAsync(() -> {
try { Thread.sleep(1000); } catch (InterruptedException e) { /* ignore */ }
return "任务1结果";
}, "数据查询");
MonitoredCompletableFuture<Integer> task2 = MonitoredCompletableFuture.supplyAsync(() -> {
try { Thread.sleep(500); } catch (InterruptedException e) { /* ignore */ }
return 42;
}, "计算任务");
CompletableFuture<String> combined = task1.getFuture()
.thenCombine(task2.getFuture(), (r1, r2) -> r1 + " + " + r2);
String result = combined.join();
System.out.println("组合结果: " + result);
}
/**
* 调试工具:打印执行线程
*/
public static <T> CompletableFuture<T> withDebug(CompletableFuture<T> future, String operation) {
return future
.thenApply(result -> {
System.out.printf("🔍 [%s] thenApply - 线程: %s, 结果: %s%n",
operation, Thread.currentThread().getName(), result);
return result;
})
.exceptionally(throwable -> {
System.out.printf("🔍 [%s] exceptionally - 线程: %s, 异常: %s%n",
operation, Thread.currentThread().getName(), throwable.getMessage());
throw new CompletionException(throwable);
});
}
public void debugExample() {
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
System.out.println("初始任务线程: " + Thread.currentThread().getName());
return "初始数据";
});
CompletableFuture<String> debugFuture = withDebug(future, "阶段1")
.thenApplyAsync(data -> {
System.out.println("异步转换线程: " + Thread.currentThread().getName());
return data + " -> 转换后";
})
.thenApply(data -> {
System.out.println("同步转换线程: " + Thread.currentThread().getName());
return data + " -> 最终结果";
});
String result = debugFuture.join();
System.out.println("调试示例结果: " + result);
}
}
总结
核心要点回顾 🎯
基础操作:
supplyAsync/runAsync- 创建异步任务thenApply- 转换结果thenAccept- 消费结果thenRun- 执行后续操作
组合操作:
thenCompose- 扁平化链式调用thenCombine- 合并两个任务结果allOf- 等待所有任务完成anyOf- 获取最快任务结果
异常处理:
exceptionally- 异常恢复handle- 统一处理成功和异常whenComplete- 完成时回调
最佳实践:
- 合理使用异步:IO密集型任务适合异步,CPU密集型需谨慎
- 避免阻塞操作:在异步任务中避免同步阻塞调用
- 合理设置超时 :使用
completeOnTimeout或orTimeout - 资源清理:及时关闭自定义线程池
- 监控调试:添加监控指标便于问题排查
性能优化技巧 ⚡
- 使用自定义线程池避免公共线程池耗尽
- 合理设置线程数:IO密集型可多线程,CPU密集型要谨慎
- 避免过度拆分:小任务过多会增加调度开销
- 使用批量操作减少线程切换
- 合理使用缓存避免重复计算
常见陷阱 🚨
- 异常被吞没 :记得使用
exceptionally或handle处理异常 - 线程池耗尽:监控线程池状态,合理设置参数
- 内存泄漏:及时取消不再需要的 Future
- 死锁风险:避免在异步任务中等待其他 Future
记住:CompletableFuture 是强大的工具,但需要根据具体场景合理使用!