1 Future和CompletableFuture的区别是什么?
1.1 功能范围差异
- Future
仅提供基础异步任务状态查询(isDone/isCancelled)和结果获取(get()方法),无法实现任务链式调用或组合,需手动处理阻塞逻辑。 - CompletableFuture
支持链式调用、组合任务(如thenApply、thenCombine等)和函数式编程,内置异常处理(exceptionally方法)与超时控制,可构建复杂异步流程。
1.2 阻塞与非阻塞特性
- Future
必须通过阻塞式get()方法等待结果返回,易造成线程资源浪费。 - CompletableFuture
提供join()非阻塞等待方法,支持回调机制(如whenComplete)自动触发后续操作,减少线程空转。
1.3 线程管理机制
- Future
依赖外部ExecutorService提交任务,需手动管理线程池资源。 - CompletableFuture
默认使用ForkJoinPool.commonPool(),支持自定义线程池,通过CAS无锁机制实现高效并发
1.4 异常处理方式
- Future
任务异常仅在调用get()时抛出ExecutionException,需手动捕获处理。 - CompletableFuture
通过exceptionally()方法捕获异常并返回默认值,支持异常传播到后续链式操作。
1.5 任务组合能力对比
- Future
多个任务需通过循环或手动协调实现组合,代码复杂度高。 - CompletableFuture
内置allOf/anyOf等多任务协调方法,支持结果聚合与依赖编排,实现"异步流水线处理。
1.6 总结
Future是基础异步模型,适合单一任务场景;CompletableFuture通过组合式编程和函数式特性,成为现代Java高并发编程的核心工具。
2 CompletableFuture详解
2.1 CompletableFuture 基础
什么是 CompletableFuture?
-
定义:Java 8 引入的异步编程工具,支持非阻塞、链式调用和任务组合。
-
特点:
- 基于 Future 的扩展,提供更丰富的异步操作。
- 支持函数式编程(如 Lambda 表达式)。
- 可手动完成任务或设置异常。
核心方法分类
方法类型 | 示例方法(有返回值/无返回值) | 用途 |
---|---|---|
任务创建 | supplyAsync/runAsync | 启动异步任务 |
链式处理 | thenApply/thenAccept | 对结果进行转换或消费 |
任务组合 | thenCompose/thenCombine | 组合多个 CompletableFuture |
异常处理 | exceptionally/handle | 处理异步任务中的异常 |
手动控制 | complete/completeExceptionally | 主动设置任务结果或异常 |
批量任务 | allOf/anyOf | 等待多个任务完成 |
2.2 核心方法详解
2.2.1 创建/获取结果和出发计算
创建
<span leaf="" class="js_darkmode__text__61">supplyAsync</span>
-
用途:提交有返回值的异步任务。
-
参数:
<span leaf="" class="js_darkmode__text__64">Supplier<U></span>
: 提供结果的函数。<span leaf="" class="js_darkmode__text__66">Executor</span>
**(可选):自定义线程池(默认使用 **<span leaf="" class="js_darkmode__text__68">ForkJoinPool</span>
(守护线程、分治理念))。
-
示例:
CompletableFuture<String> future =CompletableFuture.supplyAsync(()->{
// 模拟耗时操作
return"Result";
});
<span leaf="" class="js_darkmode__text__92">runAsync</span>
-
用途:提交无返回值的异步任务(Runnable)。
-
参数:
<span leaf="" class="js_darkmode__text__95">Runnable</span>
: 无返回值的任务。<span leaf="" class="js_darkmode__text__97">Executor</span>
(可选):自定义线程池。
CompletableFuture<Void> future =CompletableFuture.runAsync(()->{
System.out.println("Task executed");
});
获取结果出发计算
publicTget()// 死等
publicTget(Long timeout,TimeUnit unit)// 超时抛出异常
publicTjoin()// 不需要抛出异常
publicTgetNow(T valueIfAbsent)//如果没有计算完结果,则给默认值(立即获取结果不阻塞)
publicbooleancomplete(T value)// 如果计算完成返回True,否则返回False
2.2.2 对结果进行处理/消费
<span leaf="" class="js_darkmode__text__166">thenApply</span>
<span leaf="" class="js_darkmode__text__167">handle</span>
和<span leaf="" class="js_darkmode__text__169">thenApply</span>
类似,
<span leaf="" class="js_darkmode__text__171">thenApply</span>
遇到异常直接中断,不执行回调,会中断。<span leaf="" class="js_darkmode__text__173">handle</span>
可同时处理正常结果和异常,继续执行后续逻辑,不会中断。- **用途:对结果进行转换(类似 **
<span leaf="" class="js_darkmode__text__176">Stream.map</span>
)。任务<span leaf="" class="js_darkmode__text__178">A</span>
执行完执行<span leaf="" class="js_darkmode__text__180">B</span>
,<span leaf="" class="js_darkmode__text__182">B</span>
需要<span leaf="" class="js_darkmode__text__184">A</span>
的结果,同时任务<span leaf="" class="js_darkmode__text__186">B</span>
有返回值。 - 参数:
<span leaf="" class="js_darkmode__text__189">Function<T, U></span>
,接受输入<span leaf="" class="js_darkmode__text__191">T</span>
,返回<span leaf="" class="js_darkmode__text__193">U</span>
。 - 示例
CompletableFuture<Integer> future =CompletableFuture.supplyAsync(()->"10")
.thenApply(s ->Integer.parseInt(s));// 转换为整数
<span leaf="" class="js_darkmode__text__225">thenAccept</span>
- 用途:消费结果(不返回新值)。任务
<span leaf="" class="js_darkmode__text__227">A</span>
执行完执行<span leaf="" class="js_darkmode__text__229">B</span>
,<span leaf="" class="js_darkmode__text__231">B</span>
需要<span leaf="" class="js_darkmode__text__233">A</span>
的结果,但是任务<span leaf="" class="js_darkmode__text__235">B</span>
无返回值。 - 参数:
<span leaf="" class="js_darkmode__text__238">Consumer<T></span>
,接受输入<span leaf="" class="js_darkmode__text__240">T</span>
,无返回值。 - 示例
CompletableFuture.supplyAsync(()->"Result")
.thenAccept(s ->System.out.println("Received: "+ s));
<span leaf="" class="js_darkmode__text__269">thenRun</span>
- 用途:在任务完成后执行操作(不访问结果)。任务
<span leaf="" class="js_darkmode__text__271">A</span>
执行完执行<span leaf="" class="js_darkmode__text__273">B</span>
,并且<span leaf="" class="js_darkmode__text__275">B</span>
不需要<span leaf="" class="js_darkmode__text__277">A</span>
的结果。 - 参数:Runnable。
- 示例:
CompletableFuture.supplyAsync(()->"Result")
.thenRun(()->System.out.println("Task finished"));
2.2.3 组合多个任务
<span leaf="" class="js_darkmode__text__307">thenCompose</span>
- 用途:将两个异步任务串联(前一个结果作为后一个任务的输入)。
- 参数:
<span leaf="" class="js_darkmode__text__310">Function<T, CompletableFuture<U>></span>
。 - 示例:
CompletableFuture<Integer> future =CompletableFuture.supplyAsync(()->"10")
.thenCompose(s ->CompletableFuture.supplyAsync(()->Integer.parseInt(s)));
<span leaf="" class="js_darkmode__text__349">thenCombine</span>
- 用途:合并两个独立任务的结果。
- 参数:
<span leaf="" class="js_darkmode__text__352">CompletionStage<U></span>
:另一个任务。
<span leaf="" class="js_darkmode__text__354">BiFunction<T, U, V></span>
:合并函数。 - 示例
CompletableFuture<Integer> futureA =CompletableFuture.supplyAsync(()->10);
CompletableFuture<Integer> futureB =CompletableFuture.supplyAsync(()->20);
futureA.thenCombine(futureB,(a, b)-> a + b)
.thenAccept(sum ->System.out.println("Sum: "+ sum));// 输出 30
<span leaf="" class="js_darkmode__text__423">allOf 和 anyOf</span>
<span leaf="" class="js_darkmode__text__424">allOf</span>
:等待所有任务完成。
CompletableFuture<Integer> futureA =CompletableFuture.supplyAsync(()->10);
CompletableFuture<Integer> futureB =CompletableFuture.supplyAsync(()->20);
CompletableFuture<Void> all =CompletableFuture.allOf(futureA, futureB);
all.thenRun(()->System.out.println("All tasks done"));
List<Object> list =Stream.of(futureA, futureB, futureC)// 获取所有的结果
.map(CompletableFuture::join)// 直接获取结果,不抛受检异常,不会阻塞,因为 allOf 已确保完成
.collect(Collectors.toList());
<span leaf="" class="js_darkmode__text__525">anyOf</span>
:等待任一任务完成。
CompletableFuture<Object> any =CompletableFuture.anyOf(futureA, futureB);
any.thenAccept(result ->System.out.println("First result: "+ result));
2.2.4 异常处理
<span leaf="" class="js_darkmode__text__561">exceptionally</span>
- 用途:捕获异常并提供默认值。
- 参数:
<span leaf="" class="js_darkmode__text__564">Function<Throwable, T></span>
,返回降级结果。 - 示例:
CompletableFuture<Integer> future =CompletableFuture.supplyAsync(()->{
if(error)thrownewRuntimeException("Error");
return10;
}).exceptionally(ex ->{
System.out.println("Error: "+ ex.getMessage());
return0;// 返回默认值
});
<span leaf="" class="js_darkmode__text__625">handle</span>
- 用途:无论成功或失败,统一处理结果和异常。
- 参数:
<span leaf="" class="js_darkmode__text__628">BiFunction<T, Throwable, U></span>
。 - 示例:
CompletableFuture<Integer> future =CompletableFuture.supplyAsync(()->10)
.handle((result, ex)->{
if(ex !=null)return0;
return result *2;
});
2.2.5 手动控制任务
<span leaf="" class="js_darkmode__text__674">complete</span>
- 用途:手动设置任务结果(如果未完成)。
CompletableFuture<String> future =newCompletableFuture<>();
future.complete("Manual Result");// 立即完成
<span leaf="" class="js_darkmode__text__697">completeExceptionally</span>
- 用途:手动设置任务异常。
future.completeExceptionally(newRuntimeException("Failed"));
3 高级操作(Java 9+)
<span leaf="" class="js_darkmode__text__711">orTimeout</span>
- **用途:设置任务超时时间,超时抛出 **
<span leaf="" class="js_darkmode__text__713">TimeoutException</span>
。
CompletableFuture<String> future =CompletableFuture.supplyAsync(()->{
Thread.sleep(2000);
return"Result";
}).orTimeout(1,TimeUnit.SECONDS);// 1秒超时
<span leaf="" class="js_darkmode__text__752">completeOnTimeout</span>
- 用途:超时后提供默认值。
CompletableFuture<String> future =CompletableFuture.supplyAsync(()->{
Thread.sleep(2000);
return"Result";
}).completeOnTimeout("Timeout",1,TimeUnit.SECONDS);
4 最佳实践
- 避免阻塞 get():尽量使用回调(如 thenAccept)替代 get()。
- 合理使用线程池
// 自定义线程池(避免耗尽默认线程池资源)
ExecutorService executor =Executors.newFixedThreadPool(10);
CompletableFuture.supplyAsync(()->task(), executor);
- 避免回调地狱:通过链式调用拆分复杂逻辑。
- **处理异常:始终使用 **
<span leaf="" class="js_darkmode__text__822">exceptionally</span>
或<span leaf="" class="js_darkmode__text__824">handle</span>
处理可能的异常。
5 完整示例
publicclassCompletableFutureDemo{
publicstaticvoidmain(String[] args)throwsException{
// 创建异步任务
CompletableFuture<Integer> futureA =CompletableFuture.supplyAsync(()->10);
CompletableFuture<Integer> futureB =CompletableFuture.supplyAsync(()->20);
// 合并结果并处理异常
CompletableFuture<Integer> combined = futureA.thenCombine(futureB,(a, b)-> a + b)
.exceptionally(ex ->{
System.out.println("Error: "+ ex.getMessage());
return0;
});
// 非阻塞获取结果
combined.thenAccept(sum ->System.out.println("Sum: "+ sum));
// 阻塞等待任务完成(仅演示)
combined.get();
}
}
评论区