CompletableFuture高级用法
=====================
`CompletableFuture` 是Java 8引入的一个类,它实现了`Future`接口和`CompletionStage`接口,提供了异步编程的能力。`CompletableFuture`可以用来编写非阻塞的代码,并且可以通过链式调用来组合多个异步操作。
原理:
CompletableFuture
的核心原理是在计算完成时触发依赖动作的执行。它包含了一系列的完成阶段(completion stages),每个阶段都是计算的一步,可以同步或异步地执行。当一个阶段的计算完成时,它可以触发一个或多个后续阶段的执行。
CompletableFuture
使用ForkJoinPool
作为其默认的异步执行机制,但也可以指定其他的Executor
来执行异步任务。它提供了多种方法来创建、完成、组合和处理异步计算的结果。
CompletableFuture
的高级用法:
1. 组合多个 CompletableFuture
–thenCombine
和 thenCombineAsync
:允许你将两个异步计算的结果合并成一个。
–thenCompose
和 thenComposeAsync
:允许你将一个异步计算的结果作为另一个异步计算的输入。
2. 处理异步结果
–thenApply
和 thenApplyAsync
:允许你对异步计算的结果进行处理和转换。
thenAccept
和thenAcceptAsync
:允许你对异步计算的结果执行某些操作,但不返回结果。
–thenRun
和 thenRunAsync
:在两个阶段都执行完后,执行一个 Runnable,不关心前一个结果。
3. 处理异常
–exceptionally
:允许你处理异步操作中的异常,并返回一个替代的结果。
–handle
和 handleAsync
:允许你处理异步操作的结果或异常。
4. 异步操作的组合
–allOf
:等待所有给定的 CompletableFuture
对象完成。
–anyOf
:等待给定的 CompletableFuture
对象中的任意一个完成。
5. 异步执行任务
–runAsync
:异步执行一个 Runnable 任务。
–supplyAsync
:异步执行一个 Supplier 任务,并返回一个 CompletableFuture
以获取结果。
6. 响应 CompletableFuture 的完成
–whenComplete
和whenCompleteAsync
:在 CompletableFuture
完成时执行一个动作。
7. 使用自定义 Executor
- 通过提供一个
Executor
,你可以控制异步任务的执行,例如定义线程池的大小。
8. 延迟执行和超时
–orTimeout
:如果 CompletableFuture
在指定时间内未完成,则完成它并抛出 TimeoutException
。
–completeOnTimeout
:如果 CompletableFuture
在指定时间内未完成,则用默认值完成它。
示例代码:
创建一个异步操作
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
// 模拟长时间运行的异步任务
sleep(1000);
return "Hello";
});
使用 thenApply 对异步结果进行处理
CompletableFuture<String> greetingFuture = future.thenApply(name -> name + ", World!");
组合两个独立的 CompletableFuture
CompletableFuture<String> combinedFuture = greetingFuture.thenCombine(
CompletableFuture.supplyAsync(() -> " from CompletableFuture!"),
(greeting, addition) -> greeting + addition
);
处理最终结果或异常
combinedFuture.whenComplete((result, ex) -> {
if (ex != null) {
System.out.println("Something went wrong: " + ex.getMessage());
} else {
System.out.println(result); // 输出 "Hello, World! from CompletableFuture!"
}
});
超时异常:
import java.util.concurrent.*;
public class CompletableFutureExample {
public static void main(String[] args) {
// 创建一个将在未来某个时间点完成的 CompletableFuture
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
// 模拟一个长时间运行的任务
try {
TimeUnit.SECONDS.sleep(5); // 假设任务需要5秒钟完成
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
return "任务结果";
});
// 设置超时时间为3秒,如果超时则返回默认值 "超时默认值"
CompletableFuture<String> timeoutFuture = future.completeOnTimeout("超时默认值", 3, TimeUnit.SECONDS);
// 获取最终结果,不会抛出异常,如果超时则返回 "超时默认值"
try {
String result = timeoutFuture.get(); // 这里会阻塞直到 future 完成或超时
System.out.println(result);
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
}
总结:
在上面的代码中,我们创建了一个 CompletableFuture
,它将在5秒后完成。然后我们使用 completeOnTimeout
方法设置了一个3秒的超时时间,并指定了一个超时后的默认返回值 “超时默认值”。
由于原始的 CompletableFuture
需要5秒才能完成,但我们设置了3秒的超时,所以 timeoutFuture
将会在3秒后由于超时而返回 “超时默认值”。
请注意,completeOnTimeout
方法是在 Java 9 及更高版本中引入的,如果你使用的是 Java 8 或更低版本,那么这个方法是不可用的
使用 CompletableFuture
的高级用法可以帮助你构建复杂的异步逻辑,优化性能,并提高代码的可读性和可维护性。CompletableFuture
提供了强大的工具集来处理复杂的异步逻辑。通过合理使用这些工具,可以构建出高效、可读性好、易于维护的异步程序。
原文链接: https://juejin.cn/post/7356078518097526784
文章收集整理于网络,请勿商用,仅供个人学习使用,如有侵权,请联系作者删除,如若转载,请注明出处:http://www.cxyroad.com/17201.html