Java使用CompletableFuture实现异步编程
1. 为什么选择 CompletableFuture?
传统的异步编程通常依赖于回调或 Future,但这些方法存在一些缺陷:
- 回调地狱:嵌套层级多,代码难以阅读。
- Future 的
get()方法是阻塞的,无法真正实现非阻塞式编程。
CompletableFuture 的优势在于:
- 支持非阻塞操作。
- 提供丰富的 API 用于任务的组合和处理。
- 更好的错误处理机制。
2. 基本用法
创建一个 CompletableFuture
import java.util.concurrent.CompletableFuture;
public class CompletableFutureExample {
public static void main(String[] args) {
// 创建一个异步任务
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(1000); // 模拟耗时操作
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
return "Hello, CompletableFuture!";
});
// 非阻塞地获取结果
future.thenAccept(result -> System.out.println("Result: " + result));
System.out.println("Main thread is not blocked");
// 防止主线程退出过早
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
输出
Main thread is not blocked Result: Hello, CompletableFuture!
3. 任务组合
thenApply: 转换结果
thenApply 方法用于将异步任务的结果转换为另一种类型。
CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> "42")
.thenApply(Integer::parseInt)
.thenApply(num -> num * 2);
future.thenAccept(result -> System.out.println("Final Result: " + result));
thenCompose: 链式调用
thenCompose 用于在一个任务完成后启动另一个异步任务。
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> "Hello")
.thenCompose(s -> CompletableFuture.supplyAsync(() -> s + " World!"));
future.thenAccept(System.out::println);
thenCombine: 合并两个任务
thenCombine 用于合并两个独立的异步任务的结果。
CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> "Hello"); CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> "World"); CompletableFuture<String> result = future1.thenCombine(future2, (s1, s2) -> s1 + " " + s2); result.thenAccept(System.out::println);
4. 异常处理
在异步任务中,异常处理非常重要。CompletableFuture 提供了多种方法来优雅地处理异常。
exceptionally: 捕获异常并返回默认值
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
if (true) {
throw new RuntimeException("Something went wrong");
}
return "Success";
}).exceptionally(ex -> {
System.out.println("Exception: " + ex.getMessage());
return "Default Value";
});
future.thenAccept(System.out::println);
handle: 处理结果和异常
handle 方法无论任务成功还是失败都会执行,并可以访问异常信息。
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
if (true) {
throw new RuntimeException("Error occurred");
}
return "Success";
}).handle((result, ex) -> {
if (ex != null) {
System.out.println("Exception: " + ex.getMessage());
return "Recovered from error";
}
return result;
});
future.thenAccept(System.out::println);
5. 实际应用场景
并发请求处理
在需要同时处理多个请求时,可以利用 allOf 或 anyOf 方法。
allOf: 等待所有任务完成
CompletableFuture<Void> allTasks = CompletableFuture.allOf(
CompletableFuture.runAsync(() -> System.out.println("Task 1")),
CompletableFuture.runAsync(() -> System.out.println("Task 2")),
CompletableFuture.runAsync(() -> System.out.println("Task 3"))
);
allTasks.thenRun(() -> System.out.println("All tasks completed"));
anyOf: 任意任务完成即返回
CompletableFuture<Object> anyTask = CompletableFuture.anyOf(
CompletableFuture.supplyAsync(() -> "Task 1 completed"),
CompletableFuture.supplyAsync(() -> "Task 2 completed")
);
anyTask.thenAccept(result -> System.out.println("First completed: " + result));
6. 总结
CompletableFuture 是 Java 异步编程的强大工具,提供了丰富的 API 来实现任务的创建、组合和异常处理。通过熟练掌握 CompletableFuture,可以编写更加简洁高效的异步代码。
以上就是Java使用CompletableFuture实现异步编程的详细内容,更多关于Java CompletableFuture异步编程的资料请关注脚本之家其它相关文章!
相关文章
Spring Cloud Gateway 远程代码执行漏洞(CVE-2022-22947)的过程解析
Spring Cloud Gateway 是基于 Spring Framework 和 Spring Boot 构建的 API 网关,它旨在为微服务架构提供一种简单、有效、统一的 API 路由管理方式,这篇文章主要介绍了Spring Cloud Gateway 远程代码执行漏洞(CVE-2022-22947),需要的朋友可以参考下2022-08-08
SpringBoot多数据源配置详细教程(JdbcTemplate、mybatis)
这篇文章主要介绍了SpringBoot多数据源配置详细教程(JdbcTemplate、mybatis),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧2021-03-03
Java service层获取HttpServletRequest工具类的方法
今天小编就为大家分享一篇关于Java service层获取HttpServletRequest工具类的方法,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧2018-12-12
解决mybatisPlus 中的field-strategy配置失效问题
这篇文章主要介绍了解决mybatisPlus 中的field-strategy配置失效问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧2021-02-02
关于@Component注解下的类无法@Autowired问题
这篇文章主要介绍了关于@Component注解下的类无法@Autowired问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教2022-03-03


最新评论