基于CompletableFuture的用法及说明
更新时间:2026年06月09日 15:01:33 作者:后会无期77
这段文章详细介绍了CompletableFuture的核心特性,包括异步执行与回调、任务组合与异常处理,并提供了常用方法示例,CompletableFuture适用于复杂异步流程的处理,提升系统性能,通过合理使用,可实现高效并行计算与微服务调用
CompletableFuture 概述
CompletableFuture 是 Java 8 引入的异步编程工具,属于 java.util.concurrent 包。
它扩展了 Future 接口,支持非阻塞操作、链式调用和组合多个异步任务,简化了复杂异步流程的处理。
核心特性
1.异步执行与回调
- 通过
supplyAsync或runAsync启动异步任务。 - 使用
thenApply、thenAccept等方法注册回调。
CompletableFuture.supplyAsync(() -> "Hello")
.thenApply(s -> s + " World")
.thenAccept(System.out::println);
2.任务组合
thenCompose:串联两个依赖的异步任务。
thenCombine:合并两个独立任务的结果。
CompletableFuture<String> futureA = CompletableFuture.supplyAsync(() -> "A");
CompletableFuture<String> futureB = CompletableFuture.supplyAsync(() -> "B");
futureA.thenCombine(futureB, (a, b) -> a + b)
.thenAccept(System.out::println);
3.异常处理
exceptionally:捕获异常并返回默认值。handle:无论成功或失败均执行处理逻辑。
CompletableFuture.supplyAsync(() -> 1 / 0)
.exceptionally(ex -> 0)
.thenAccept(System.out::println); // 输出 0
常用方法
1.创建异步任务
supplyAsync(Supplier<U>):返回结果的异步任务。runAsync(Runnable):无返回值的异步任务。
2.结果处理
thenApply(Function<T,U>):对结果转换。thenAccept(Consumer<T>):消费结果。
3.多任务协作
allOf(CompletableFuture<?>...):等待所有任务完成。anyOf(CompletableFuture<?>...):任一任务完成即返回。
示例代码
// 模拟异步获取用户信息
CompletableFuture<String> fetchUser = CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "User123";
});
// 异步获取订单信息
CompletableFuture<String> fetchOrder = CompletableFuture.supplyAsync(() -> "Order456");
// 合并结果
fetchUser.thenCombine(fetchOrder, (user, order) -> user + " - " + order)
.thenAccept(System.out::println); // 输出 "User123 - Order456"
注意事项
- 线程池管理:默认使用
ForkJoinPool.commonPool(),可通过重载方法指定自定义线程池。 - 避免阻塞:
get()方法会阻塞线程,推荐使用回调或join()(仅在明确需要时使用)。 - 异常传播:未处理的异常会导致任务静默失败,需显式捕获。
CompletableFuture 适用于需要编排多个异步操作的场景,如微服务调用、并行计算等,能显著提升系统的响应速度和资源利用率。
批量执行
ExecutorService executor = Executors.newFixedThreadPool(2);
List<User> userList = new ArrayList<>();
for(int i = 0;i< 5;i++){
userList.add(new User((100+i)+"","test"+i));
}
List<CompletableFuture<ERUser>> completableFutureList = userList.stream().map(user->CompletableFuture.supplyAsync(()->{
ERUser erUser = new ERUser();
erUser.setName(user.getUserName());
log.info("线程id:"+Thread.currentThread().getName()+",user转ERUser"+ user.getUserName());
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return erUser;
},executor).exceptionally( ex->{
//异常捕获
return null;
})).collect(Collectors.toList());
List<ERUser> erUsers = completableFutureList.stream()
.map(CompletableFuture::join)
.collect(Collectors.toList());
executor.shutdown();
log.info(erUsers.size()+"");

总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。


最新评论