Future / CompletableFuture区别java1.8中(ds)
在 Java 8 中,Future
和 CompletableFuture
都是处理异步计算的接口,但它们在功能和使用方式上有显著区别:
1. Future
(java.util.concurrent
包)
-
基本定位:
表示异步计算的结果(只读视图)。提供基础能力:检查计算是否完成、阻塞获取结果、取消任务。 -
关键方法:
boolean cancel(boolean mayInterrupt); // 取消任务 V get() throws ...; // 阻塞获取结果 V get(long timeout, TimeUnit unit); // 限时阻塞获取结果 boolean isDone(); // 是否完成(含正常/异常/取消) boolean isCancelled(); // 是否被取消
-
局限性:
-
阻塞获取结果:
get()
方法会阻塞线程直到计算完成。 -
无法手动设置结果:不能主动完成一个
Future
(如设置值或异常)。 -
缺少组合能力:难以实现“任务A完成后触发任务B”的链式调用。
-
无回调机制:不支持计算结果就绪后的自动通知。
-
2. CompletableFuture
(java.util.concurrent
包,Java 8 新增)
-
基本定位:
扩展了Future
并实现了CompletionStage
接口,支持非阻塞操作、链式调用、组合异步任务。 -
核心优势:
-
手动完成能力:可主动设置结果或异常。
completableFuture.complete("Result"); // 手动设置结果 completableFuture.completeExceptionally(ex); // 手动设置异常
-
非阻塞回调:通过回调函数处理结果,避免阻塞线程。
cf.thenAccept(result -> System.out.println(result)); // 结果就绪时自动处理
-
链式组合:支持函数式风格的流水线操作。
cf.thenApply(String::toUpperCase) .thenApply(s -> s + "!") .thenAccept(System.out::println);
-
任务组合:合并多个异步任务的结果。
CompletableFuture<String> cf1 = ...; CompletableFuture<String> cf2 = ...; cf1.thenCombine(cf2, (res1, res2) -> res1 + res2); // 合并两个结果
-
异常处理:专用方法处理异常。
cf.exceptionally(ex -> "Fallback Value"); // 异常时返回默认值
-
关键区别总结
特性 | Future | CompletableFuture |
---|---|---|
结果获取 | 阻塞(get() ) |
非阻塞(回调) |
手动完成 | ❌ 不支持 | ✅ complete() /completeExceptionally() |
链式调用 | ❌ 需自行实现 | ✅ thenApply() /thenAccept() /thenRun() |
任务组合 | ❌ 复杂且易出错 | ✅ allOf() /anyOf() /thenCombine() |
异常处理 | 需在 get() 中捕获 ExecutionException |
✅ exceptionally() /handle() |
异步执行 | 需配合 ExecutorService |
✅ runAsync() /supplyAsync() |
函数式编程支持 | ❌ 无 | ✅ 方法接受 Function /Consumer 等参数 |
何时使用?
-
Future
:
简单异步场景(如ExecutorService.submit()
),只需基础结果获取能力。 -
CompletableFuture
:
复杂异步流程(如链式调用、多任务合并、事件驱动),需要非阻塞、响应式编程。
代码示例(CompletableFuture
)
// 异步执行 + 链式调用 + 异常处理
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") |
完整使用示例
// 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(); // 阻塞等待结果(实际开发中应避免在主线程阻塞)
关键实践建议
-
避免阻塞:尽量使用回调(
thenAccept/thenApply
)代替get()
-
指定线程池:默认使用
ForkJoinPool
,高负载场景需自定义线程池ExecutorService customPool = Executors.newFixedThreadPool(10); CompletableFuture.supplyAsync(() -> task(), customPool);
-
异常传播:使用
handle()
或whenComplete()
确保异常不丢失 -
资源清理:在
whenComplete()
中关闭资源(如文件句柄、网络连接)
注意:Java 8 的
CompletableFuture
不支持超时控制(Java 9 新增orTimeout
/completeOnTimeout
),需自行实现超时逻辑。