可能出现的性能瓶颈
- 线程开销:每个
CompletableFuture
可能涉及线程的创建与切换,高并发时线程上下文切换开销大。
- 异常处理开销:
handle
方法处理异常时,频繁的异常对象创建和栈回溯带来性能损耗。
- 资源竞争:如果共享资源(如数据库连接等)被多个
CompletableFuture
访问,可能产生资源竞争,导致等待。
性能优化方案
- 线程池优化:
- 方案:使用自定义线程池,合理配置线程池大小。通过
Executors.newFixedThreadPool(int nThreads)
创建固定大小线程池,避免系统默认线程池创建过多线程。
- 权衡:资源利用上,合理的线程数可避免线程过多消耗资源;代码复杂度稍有增加,需手动管理线程池;可维护性方面,线程池配置有文档说明则便于维护。
- 批量处理异常:
- 方案:使用
CompletableFuture.allOf
方法收集所有 CompletableFuture
,在最后统一处理异常,减少每个 CompletableFuture
的 handle
调用。
- 权衡:资源利用上,减少异常处理开销;代码复杂度增加,需重新组织代码逻辑;可维护性上,集中处理异常使异常处理逻辑更清晰。
示例代码
import java.util.concurrent.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
public class CompletableFutureOptimization {
private static final ExecutorService executorService = Executors.newFixedThreadPool(10);
public static void main(String[] args) {
// 模拟多个任务
var futures = IntStream.range(0, 100)
.mapToObj(i -> CompletableFuture.supplyAsync(() -> {
if (Math.random() < 0.1) {
throw new RuntimeException("模拟异常");
}
return "任务 " + i + " 正常完成";
}, executorService))
.collect(Collectors.toList());
// 批量处理异常
CompletableFuture<Void> allFutures = CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]));
allFutures.join();
futures.forEach(future -> {
future.exceptionally(ex -> {
System.out.println("捕获异常: " + ex.getMessage());
return "处理异常后返回的结果";
}).thenAccept(System.out::println);
});
executorService.shutdown();
}
}