下面是一份关于 CompletableFuture 实战应用的指南:
一、核心应用场景
1. 异步任务链
CompletableFuture.supplyAsync(() -> fetchDataFromDB()) // 异步查询数据库
.thenApply(data -> processData(data)) // 同步处理数据
.thenAccept(result -> saveResultToCache(result)) // 异步保存结果
.exceptionally(ex -> handleError(ex)); // 统一异常处理
2. 多任务并行聚合
CompletableFuture<String> futureA = CompletableFuture.supplyAsync(() -> callServiceA());
CompletableFuture<String> futureB = CompletableFuture.supplyAsync(() -> callServiceB());
CompletableFuture.allOf(futureA, futureB)
.thenApply(v -> combineResults(futureA.join(), futureB.join()))
.thenAccept(System.out::println);
3. 超时控制
CompletableFuture.supplyAsync(() -> longRunningTask())
.completeOnTimeout("fallback_value", 2, TimeUnit.SECONDS) // 超时返回默认值
.thenAccept(System.out::println);
二、常见陷阱与规避
阻塞主线程
避免在异步任务中调用 .join() 或 .get() 阻塞主线程,优先使用回调链。
异常未处理
务必通过 .exceptionally() 或 .handle() 捕获异常:
.handle((result, ex) -> ex != null ? "error" : result)
线程池滥用
默认使用 ForkJoinPool.commonPool(),高并发场景需自定义线程池:
ExecutorService customPool = Executors.newFixedThreadPool(10);
CompletableFuture.supplyAsync(() -> task(), customPool);
三、高阶优化策略
1. 组合依赖任务
CompletableFuture<String> futureC = futureA.thenCompose(
a -> CompletableFuture.supplyAsync(() -> callServiceC(a))
);
2. 结果选择器
CompletableFuture.supplyAsync(() -> callServiceX())
.applyToEither(
CompletableFuture.supplyAsync(() -> callServiceY()),
firstResult -> firstResult // 取最先响应的结果
);
3. 自定义回调线程
通过 thenApplyAsync 指定后续操作线程池:
.thenApplyAsync(result -> heavyComputation(result), customPool)
四、性能监控
Metrics.timer("async_task").record(() -> future.join());
五、最佳实践总结
- 线程池隔离:IO密集型与CPU密集型任务使用不同线程池
- 链式拆解:单一职责的链式调用,避免超长回调链
- 防御式编程:所有异步操作必须包含超时和异常处理
- 资源释放:在 .whenComplete() 中关闭数据库连接等资源
通过以上策略,可显著提升高并发场景下的响应速度和系统稳定性。
网硕互联帮助中心



评论前必须登录!
注册