Java 8 异步编程和非阻塞操作工具 CompletableFuture
CompletableFuture
是 Java 8 引入的一个强大工具,用于处理异步编程和非阻塞操作。它实现了 Future
和 CompletionStage
接口,结合了两者的功能,使异步编程更加灵活和高效。
核心功能与用法
1. 创建异步任务
使用 supplyAsync
(有返回值)或 runAsync
(无返回值)方法创建异步任务:
java
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;public class CompletableFutureExample {public static void main(String[] args) {// 使用 ForkJoinPool.commonPool() 执行异步任务(有返回值)CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> {try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); }return "Result from future1";});// 使用自定义线程池执行异步任务(无返回值)ExecutorService executor = Executors.newSingleThreadExecutor();CompletableFuture<Void> future2 = CompletableFuture.runAsync(() -> {try { Thread.sleep(1000); } catch (InterruptedException e) {e.printStackTrace(); }System.out.println("Task from future2 completed");}, executor);executor.shutdown();}
}
2. 链式处理结果
通过 thenApply
、thenAccept
、thenRun
等方法链式处理异步结果:
java
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> "Hello")// 处理结果并返回新值.thenApply(s -> s + " World") // 消费结果(无返回值).thenAccept(System.out::println) // 执行后续操作.thenRun(() -> System.out.println("Task completed"));
3. 组合多个异步任务
使用 thenCompose
、thenCombine
、allOf
、anyOf
等方法组合多个 CompletableFuture
:
java
// 串行组合:一个任务依赖另一个任务的结果
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> "Hello").thenCompose(s -> CompletableFuture.supplyAsync(() -> s + " World"));// 并行组合:两个任务完成后合并结果
CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> "Hello");CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> " World");CompletableFuture<String> combined = future1.thenCombine(future2, (s1, s2) -> s1 + s2);// 等待所有任务完成
CompletableFuture<Void> allFutures = CompletableFuture.allOf(future1, future2);
allFutures.thenRun(() -> System.out.println("All tasks completed"));// 任意一个任务完成即返回
CompletableFuture<Object> anyFuture = CompletableFuture.anyOf(future1, future2);anyFuture.thenAccept(result -> System.out.println("One task completed: " + result)
);
4. 异常处理
使用 exceptionally
、handle
或 whenComplete
处理异常:
java
CompletableFuture<String> future= CompletableFuture.supplyAsync(() -> {if (Math.random() < 0.5) {throw new RuntimeException("Something went wrong");}return "Success";
})
// 异常时返回默认值
.exceptionally(ex -> "Default Value")
// 统一处理结果和异常
.handle((result, ex) -> ex != null ? "Error: " + ex.getMessage() : result);
5. 阻塞获取结果
使用 get()
或 join()
方法获取结果(会阻塞当前线程):
java
CompletableFuture<String> future= CompletableFuture.supplyAsync(() -> "Result");
try {// 可能抛出 InterruptedException 或 ExecutionExceptionString result = future.get(); // 与 get() 类似,但将异常包装为 CompletionExceptionString result2 = future.join();
} catch (Exception e) {e.printStackTrace();
}
示例:模拟电商订单处理
下面是一个更完整的示例,展示如何使用 CompletableFuture
处理复杂的异步流程:
java
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;public class EcommerceExample {public static void main(String[] args) {// 模拟用户下单CompletableFuture<Order> createOrder = CompletableFuture.supplyAsync(() -> {System.out.println("创建订单...");return new Order("ORD-12345");});// 异步验证库存CompletableFuture<Order> verifyStock = createOrder.thenApply(order -> {System.out.println("验证库存...");order.setStockVerified(true);return order;});// 异步处理支付CompletableFuture<Order> processPayment = verifyStock.thenApply(order -> {System.out.println("处理支付...");order.setPaymentSuccessful(true);return order;});// 异步发货(依赖库存验证和支付结果)CompletableFuture<Order> shipOrder = processPayment.thenApply(order -> {System.out.println("发货...");order.setShipped(true);return order;});// 通知用户(所有步骤完成后)CompletableFuture<Void> notifyUser = shipOrder.thenAccept(order -> {System.out.println("通知用户: 订单 " + order.getOrderId() + " 已发货");});// 主线程等待所有操作完成try {notifyUser.get();System.out.println("订单处理完成");} catch (InterruptedException | ExecutionException e) {e.printStackTrace();}}static class Order {private String orderId;private boolean stockVerified;private boolean paymentSuccessful;private boolean shipped;public Order(String orderId) {this.orderId = orderId;}// Getters and setterspublic String getOrderId() { return orderId; }public void setStockVerified(boolean stockVerified) {this.stockVerified = stockVerified; }public void setPaymentSuccessful(boolean paymentSuccessful) {this.paymentSuccessful = paymentSuccessful; }public void setShipped(boolean shipped) { this.shipped = shipped; }}
}
执行结果示例
创建订单...
验证库存...
处理支付...
发货...
通知用户: 订单 ORD-12345 已发货
订单处理完成
通过 CompletableFuture
,你可以轻松构建复杂的异步流程,避免回调地狱,使代码更易读和维护。