Future / CompletableFuture区别java1.8中(ds)

 

在 Java 8 中,Future 和 CompletableFuture 都是处理异步计算的接口,但它们在功能和使用方式上有显著区别:


1. Futurejava.util.concurrent包)

  • 基本定位:
    表示异步计算的结果(只读视图)。提供基础能力:检查计算是否完成、阻塞获取结果、取消任务。

  • 关键方法:

    java
     
    boolean cancel(boolean mayInterrupt); // 取消任务
    V get() throws ...;                  // 阻塞获取结果
    V get(long timeout, TimeUnit unit);   // 限时阻塞获取结果
    boolean isDone();                    // 是否完成(含正常/异常/取消)
    boolean isCancelled();               // 是否被取消
  • 局限性:

    • 阻塞获取结果:get() 方法会阻塞线程直到计算完成。

    • 无法手动设置结果:不能主动完成一个 Future(如设置值或异常)。

    • 缺少组合能力:难以实现“任务A完成后触发任务B”的链式调用。

    • 无回调机制:不支持计算结果就绪后的自动通知。


2. CompletableFuturejava.util.concurrent包,Java 8 新增)

  • 基本定位:
    扩展了 Future 并实现了 CompletionStage 接口,支持非阻塞操作、链式调用、组合异步任务。

  • 核心优势:

    • 手动完成能力:可主动设置结果或异常。

      java
       
      completableFuture.complete("Result");      // 手动设置结果
      completableFuture.completeExceptionally(ex); // 手动设置异常
    • 非阻塞回调:通过回调函数处理结果,避免阻塞线程。

      java
       
      cf.thenAccept(result -> System.out.println(result)); // 结果就绪时自动处理
    • 链式组合:支持函数式风格的流水线操作。

      java
       
      cf.thenApply(String::toUpperCase)
        .thenApply(s -> s + "!")
        .thenAccept(System.out::println);
    • 任务组合:合并多个异步任务的结果。

      java
       
      CompletableFuture<String> cf1 = ...;
      CompletableFuture<String> cf2 = ...;
      cf1.thenCombine(cf2, (res1, res2) -> res1 + res2); // 合并两个结果
    • 异常处理:专用方法处理异常。

      java
       
      cf.exceptionally(ex -> "Fallback Value"); // 异常时返回默认值

关键区别总结

特性FutureCompletableFuture
结果获取 阻塞(get() 非阻塞(回调)
手动完成 ❌ 不支持 ✅ complete()/completeExceptionally()
链式调用 ❌ 需自行实现 ✅ thenApply()/thenAccept()/thenRun()
任务组合 ❌ 复杂且易出错 ✅ allOf()/anyOf()/thenCombine()
异常处理 需在 get() 中捕获 ExecutionException ✅ exceptionally()/handle()
异步执行 需配合 ExecutorService ✅ runAsync()/supplyAsync()
函数式编程支持 ❌ 无 ✅ 方法接受 Function/Consumer 等参数

何时使用?

  • Future
    简单异步场景(如 ExecutorService.submit()),只需基础结果获取能力。

  • CompletableFuture
    复杂异步流程(如链式调用、多任务合并、事件驱动),需要非阻塞、响应式编程。

代码示例(CompletableFuture

java
 
// 异步执行 + 链式调用 + 异常处理
CompletableFuture.supplyAsync(() -> fetchDataFromAPI())
    .thenApply(data -> processData(data))
    .thenAccept(result -> saveResult(result))
    .exceptionally(ex -> {
        log.error("Failed: ", ex);
        return null;
    });

// 合并两个异步任务结果
CompletableFuture<String> cf1 = fetchUserInfo();
CompletableFuture<String> cf2 = fetchOrderHistory();
cf1.thenCombine(cf2, (user, orders) -> buildReport(user, orders))
   .thenAccept(report -> sendReport(report));

总结:
Future 是基础的异步结果容器,而 CompletableFuture 是更强大的升级版,支持非阻塞、组合式异步编程。在 Java 8+ 中,绝大多数场景推荐使用 CompletableFuture

 

 

CompletableFuture区别java1.8中的常用api解释和使用方法

 
 

在 Java 8 中,CompletableFuture 提供了丰富的 API 用于异步编程。以下是核心 API 的分类详解和使用示例:


1. 创建异步任务

API说明示例
runAsync(Runnable) 执行无返回值的异步任务 CompletableFuture.runAsync(() -> System.out.println("Task running"))
supplyAsync(Supplier<U>) 执行有返回值的异步任务 CompletableFuture.supplyAsync(() -> "Result")
重载方法:支持指定线程池   supplyAsync(() -> "Result", customExecutor)

2. 结果转换(同步处理)

API说明示例
thenApply(Function<T,U>) 同步转换结果 .thenApply(s -> s + " processed")
thenAccept(Consumer<T>) 同步消费结果 .thenAccept(System.out::println)
thenRun(Runnable) 结果完成后执行操作 .thenRun(() -> log.info("Done"))

3. 异步链式处理

API说明示例
thenApplyAsync(Function<T,U>) 异步转换结果 .thenApplyAsync(s -> intensiveProcessing(s))
thenAcceptAsync(Consumer<T>) 异步消费结果 .thenAcceptAsync(data -> saveToDB(data))
thenRunAsync(Runnable) 异步执行操作 .thenRunAsync(() -> cleanCache())

4. 双任务组合

API说明示例
thenCombine(CompletionStage<U>, BiFunction<T,U,V>) 合并两个任务结果 futureA.thenCombine(futureB, (a, b) -> a + b)
thenAcceptBoth(CompletionStage<U>, BiConsumer<T,U>) 消费两个任务结果 futureA.thenAcceptBoth(futureB, (a, b) -> System.out.println(a + b))
runAfterBoth(CompletionStage<?>, Runnable) 两个任务完成后执行操作 futureA.runAfterBoth(futureB, () -> System.out.println("Both done"))

5. 任务竞速(任一完成)

API说明示例
applyToEither(CompletionStage<T>, Function<T,U>) 使用第一个完成的结果 futureA.applyToEither(futureB, first -> "Winner: " + first)
acceptEither(CompletionStage<T>, Consumer<T>) 消费第一个完成的结果 futureA.acceptEither(futureB, winner -> notifyUser(winner))
runAfterEither(CompletionStage<?>, Runnable) 任一任务完成后执行操作 futureA.runAfterEither(futureB, () -> log.info("One completed"))

6. 多任务协调

API说明示例
allOf(CompletableFuture<?>...) 等待所有任务完成 CompletableFuture.allOf(futures).thenRun(() -> ...)
anyOf(CompletableFuture<?>...) 等待任一任务完成 CompletableFuture.anyOf(futures).thenAccept(first -> ...)

7. 异常处理

API说明示例
exceptionally(Function<Throwable,T>) 捕获异常并返回默认值 .exceptionally(ex -> "Fallback")
handle(BiFunction<T,Throwable,U>) 无论成功/失败都处理 .handle((res, ex) -> ex != null ? "Error" : res)
whenComplete(BiConsumer<T,Throwable>) 观察结果/异常(不修改结果) .whenComplete((res, ex) -> { if (ex != null) log.error(ex); })

8. 手动控制

API说明示例
complete(T value) 手动设置结果 cf.complete("Manual result")
completeExceptionally(Throwable ex) 手动设置异常 cf.completeExceptionally(new TimeoutException())
obtrudeValue(T value) 强制覆盖结果(谨慎使用) cf.obtrudeValue("Forced value")

完整使用示例

java
 
// 1. 创建异步任务
CompletableFuture<String> fetchData = CompletableFuture.supplyAsync(() -> {
    return queryDatabase(); // 模拟数据库查询
});

// 2. 结果转换 + 异常处理
CompletableFuture<String> processed = fetchData
    .thenApplyAsync(data -> transformData(data)) // 异步转换
    .exceptionally(ex -> {                     // 异常处理
        log.error("Failed", ex);
        return "Default Value";
    });

// 3. 组合多个任务
CompletableFuture<String> fetchConfig = CompletableFuture.supplyAsync(this::loadConfig);
CompletableFuture<String> merged = processed.thenCombine(
    fetchConfig, 
    (data, config) -> mergeWithConfig(data, config)
);

// 4. 最终处理
merged.thenAccept(finalResult -> {
    System.out.println("Final result: " + finalResult);
}).join(); // 阻塞等待结果(实际开发中应避免在主线程阻塞)

关键实践建议

  1. 避免阻塞:尽量使用回调(thenAccept/thenApply)代替get()

  2. 指定线程池:默认使用ForkJoinPool,高负载场景需自定义线程池

    java
     
    ExecutorService customPool = Executors.newFixedThreadPool(10);
    CompletableFuture.supplyAsync(() -> task(), customPool);
  3. 异常传播:使用handle()whenComplete()确保异常不丢失

  4. 资源清理:在whenComplete()中关闭资源(如文件句柄、网络连接)

注意:Java 8 的 CompletableFuture 不支持超时控制(Java 9 新增orTimeout/completeOnTimeout),需自行实现超时逻辑。

 
posted @ 2025-07-15 10:30  飘来荡去evo  阅读(67)  评论(0)    收藏  举报