侧边栏壁纸
  • 累计撰写 64 篇文章
  • 累计创建 26 个标签
  • 累计收到 21 条评论

目 录CONTENT

文章目录

Future和CompletableFuture的区别是什么?

Administrator
2025-08-27 / 0 评论 / 0 点赞 / 9 阅读 / 0 字 / 正在检测是否收录...
温馨提示:
部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

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();
}
}
0

评论区