赞
踩
目录
Java的CompletableFuture
是Java 8中引入的一个功能强大的类,用于处理异步编程。它不仅提供了一种方式来表示异步计算,还提供了丰富的API来进行复杂的异步编排和处理。本文将详细讲解CompletableFuture
的基本概念、使用方法以及一些高级特性,并结合实例代码进行说明。
异步编程是一种并发编程的形式,通过非阻塞方式执行任务。传统的同步编程中,任务必须按顺序执行,每个任务必须等待前一个任务完成。然而,在异步编程中,任务可以在后台执行,主线程无需等待任务完成,因而可以继续处理其他任务。这种方式在提高程序响应速度和资源利用率方面有很大优势。
CompletableFuture
简介CompletableFuture
是Java提供的一个实现Future
接口的类,它不仅支持传统的Future
接口方法,还引入了许多新的方法来支持回调、组合、处理异常等功能。通过这些方法,开发者可以更方便地编写异步代码。
CompletableFuture
CompletableFuture
对象创建一个CompletableFuture
对象非常简单,可以通过以下几种方式:
使用CompletableFuture
的静态工厂方法:
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> "Hello, World!");
使用默认构造函数创建一个空的CompletableFuture
,然后在未来的某个时间点手动完成它:
CompletableFuture<String> future = new CompletableFuture<>(); // 在其他线程或任务中完成这个future future.complete("Hello, World!");
CompletableFuture
你可以通过complete
方法手动完成一个CompletableFuture
:
CompletableFuture<String> future = new CompletableFuture<>(); future.complete("Hello, World!");
如果已经完成的CompletableFuture
再次调用complete
,将不会改变其状态。
CompletableFuture
CompletableFuture
也可以以异常方式完成:
CompletableFuture<String> future = new CompletableFuture<>(); future.completeExceptionally(new RuntimeException("Something went wrong"));
CompletableFuture
提供了多种方法来启动异步任务,例如:
runAsync
:执行不返回结果的异步任务。
supplyAsync
:执行并返回结果的异步任务。
- CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
- // 异步执行的任务
- System.out.println("Hello from a different thread!");
- });
-
- CompletableFuture<String> futureWithResult = CompletableFuture.supplyAsync(() -> {
- // 异步执行的任务,返回结果
- return "Result of the async computation";
- });
CompletableFuture
提供了多种方法来处理异步任务的结果,例如:
thenApply
:当CompletableFuture
完成时,对其结果进行处理,并返回一个新的CompletableFuture
。
thenAccept
:当CompletableFuture
完成时,消费其结果,但不返回新的CompletableFuture
。
thenRun
:当CompletableFuture
完成时,运行一个任务,不关心其结果。
- CompletableFuture.supplyAsync(() -> "Hello")
- .thenApply(result -> result + ", World!")
- .thenAccept(System.out::println);
上述代码中,supplyAsync
方法执行异步任务并返回结果"Hello"。thenApply
方法对结果进行处理,得到"Hello, World!"。thenAccept
方法消费处理后的结果,并打印输出。
CompletableFuture
CompletableFuture
提供了多种方式来组合多个异步任务:
thenCombine
thenCombine
用于将两个CompletableFuture
的结果进行组合,并返回一个新的CompletableFuture
:
- CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> "Hello");
- CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> "World");
-
- CompletableFuture<String> combinedFuture = future1.thenCombine(future2, (result1, result2) -> result1 + " " + result2);
- combinedFuture.thenAccept(System.out::println); // 输出 "Hello World"
thenCompose
thenCompose
用于将一个CompletableFuture
的结果作为另一个CompletableFuture
的输入,类似于flatMap
:
- CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> "Hello")
- .thenCompose(result -> CompletableFuture.supplyAsync(() -> result + " World"));
-
- future.thenAccept(System.out::println); // 输出 "Hello World"
allOf
和anyOf
allOf
:等待所有提供的CompletableFuture
都完成。
anyOf
:只要任意一个CompletableFuture
完成即可。
- CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> "Result from future1");
- CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> "Result from future2");
-
- CompletableFuture<Void> allOfFuture = CompletableFuture.allOf(future1, future2);
- allOfFuture.thenRun(() -> System.out.println("All futures completed"));
-
- CompletableFuture<Object> anyOfFuture = CompletableFuture.anyOf(future1, future2);
- anyOfFuture.thenAccept(result -> System.out.println("First completed future result: " + result));
在处理异步任务时,异常处理是不可避免的。CompletableFuture
提供了多种方式来处理异常:
handle
handle
方法用于处理正常结果和异常情况:
- CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
- if (Math.random() > 0.5) {
- throw new RuntimeException("Something went wrong");
- }
- return "Success";
- });
-
- future.handle((result, ex) -> {
- if (ex != null) {
- return "Exception: " + ex.getMessage();
- }
- return result;
- }).thenAccept(System.out::println);
exceptionally
exceptionally
方法仅处理异常情况:
- CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
- if (Math.random() > 0.5) {
- throw new RuntimeException("Something went wrong");
- }
- return "Success";
- });
-
- future.exceptionally(ex -> "Exception: " + ex.getMessage())
- .thenAccept(System.out::println);
默认情况下,CompletableFuture
使用ForkJoinPool.commonPool()
作为其默认的线程池。你可以自定义执行器来控制任务的执行方式:
- Executor executor = Executors.newFixedThreadPool(10);
-
- CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> "Hello", executor)
- .thenApplyAsync(result -> result + " World", executor);
-
- future.thenAcceptAsync(System.out::println, executor);
在某些场景下,处理超时是必要的。Java 9引入了orTimeout
和completeOnTimeout
方法:
- CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
- try {
- Thread.sleep(3000);
- } catch (InterruptedException e) {
- throw new IllegalStateException(e);
- }
- return "Result";
- });
-
- future.orTimeout(1, TimeUnit.SECONDS)
- .exceptionally(ex -> "Timeout occurred: " + ex.getMessage())
- .thenAccept(System.out::println);
为了更好地理解CompletableFuture
,我们来看一个实际的例子:模拟一个复杂的业务场景,包含多个异步任务的组合和处理。
假设我们在开发一个在线购物平台,用户下单时需要进行以下操作:
验证用户信息。
检查库存。
处理支付。
生成订单。
我们希望这些操作尽可能并行执行,以提高系统的响应速度。
- import java.util.concurrent.CompletableFuture;
- import java.util.concurrent.ExecutorService;
- import java.util.concurrent.Executors;
-
- public class OnlineShopping {
-
- private static final ExecutorService executor = Executors.newFixedThreadPool(10);
-
- public static void main(String[] args) {
- CompletableFuture<Void> orderFuture = CompletableFuture.supplyAsync(() -> verifyUser("user123"), executor)
- .thenCombineAsync(CompletableFuture.supplyAsync(() -> checkInventory("item456"), executor), (userVerified, inventoryChecked) -> {
- if (userVerified && inventoryChecked) {
- return processPayment("user123", "
-
- item456");
- } else {
- throw new RuntimeException("User verification or inventory check failed");
- }
- }, executor)
- .thenApplyAsync(paymentProcessed -> generateOrder("user123", "item456"), executor)
- .thenAcceptAsync(order -> System.out.println("Order completed: " + order), executor)
- .exceptionally(ex -> {
- System.err.println("Order processing failed: " + ex.getMessage());
- return null;
- });
-
- orderFuture.join(); // 等待所有操作完成
- }
-
- private static boolean verifyUser(String userId) {
- // 模拟用户验证
- System.out.println("Verifying user: " + userId);
- return true;
- }
-
- private static boolean checkInventory(String itemId) {
- // 模拟库存检查
- System.out.println("Checking inventory for item: " + itemId);
- return true;
- }
-
- private static boolean processPayment(String userId, String itemId) {
- // 模拟支付处理
- System.out.println("Processing payment for user: " + userId + " and item: " + itemId);
- return true;
- }
-
- private static String generateOrder(String userId, String itemId) {
- // 模拟订单生成
- System.out.println("Generating order for user: " + userId + " and item: " + itemId);
- return "Order123";
- }
- }
在这个示例中,我们使用了多个CompletableFuture
来并行执行用户验证、库存检查和支付处理。所有任务都在自定义的线程池中执行,最后通过生成订单来完成整个流程。如果在任何一个步骤中发生异常,系统会捕获并处理。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。