CompletableFuture 是 Java 8 引入的一个非常强大的类,它提供了一种异步编程的方式来处理并发任务。与 Future 和 ExecutorService 不同,CompletableFuture 允许我们以声明式的方式进行异步编程,并可以实现任务的组合、错误处理、结果返回等操作。
1. 基本概念
CompletableFuture 允许你以异步的方式执行任务,并通过回调函数、链式调用等方式处理结果。它是 Future 的增强版,提供了更多的功能,如组合多个异步任务、处理异常等。
2. 使用 CompletableFuture
CompletableFuture 可以通过静态工厂方法来创建异步任务,常见的有:
supplyAsync: 异步执行并返回结果(适用于有返回值的任务)。runAsync: 异步执行没有返回值的任务。thenApply: 对结果进行转换,返回一个新的CompletableFuture。thenAccept: 处理结果但不返回值。exceptionally: 异常处理。thenCombine: 合并两个CompletableFuture的结果。
3. 代码例子
下面是一个简单的 CompletableFuture 使用示例,涵盖了异步执行、结果转换、异常处理等常见操作。
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
public class CompletableFutureExample {
public static void main(String[] args) throws ExecutionException, InterruptedException {
// 异步执行一个任务
CompletableFuture<Integer> future1 = CompletableFuture.supplyAsync(() -> {
System.out.println("Task 1 is running in thread: " + Thread.currentThread().getName());
return 10;
});
// 异步执行一个任务并处理结果
CompletableFuture<Integer> future2 = future1.thenApplyAsync(result -> {
System.out.println("Task 2 is running in thread: " + Thread.currentThread().getName());
return result * 2;
});
// 异步执行任务3并处理
CompletableFuture<Void> future3 = future2.thenAcceptAsync(result -> {
System.out.println("Task 3 is running in thread: " + Thread.currentThread().getName());
System.out.println("Result: " + result);
});
// 异常处理
CompletableFuture<Integer> future4 = CompletableFuture.supplyAsync(() -> {
if (true) {
throw new RuntimeException("Something went wrong");
}
return 100;
}).exceptionally(ex -> {
System.out.println("Exception: " + ex.getMessage());
return -1; // 返回一个默认值
});
// 等待所有任务完成
CompletableFuture.allOf(future1, future2, future3, future4).join();
// 输出最终的结果
System.out.println("Main thread: " + Thread.currentThread().getName());
}
}
4. 代码解析
-
创建异步任务
CompletableFuture<Integer> future1 = CompletableFuture.supplyAsync(() -> { System.out.println("Task 1 is running in thread: " + Thread.currentThread().getName()); return 10; });这里我们创建了一个异步任务,它返回
10。supplyAsync用于执行一个有返回值的任务。 -
对结果进行处理
CompletableFuture<Integer> future2 = future1.thenApplyAsync(result -> { System.out.println("Task 2 is running in thread: " + Thread.currentThread().getName()); return result * 2; });thenApplyAsync用于在第一个任务完成后继续执行的操作,返回一个新的CompletableFuture。这里我们将future1的结果乘以 2。 -
接收并消费结果
CompletableFuture<Void> future3 = future2.thenAcceptAsync(result -> { System.out.println("Task 3 is running in thread: " + Thread.currentThread().getName()); System.out.println("Result: " + result); });thenAcceptAsync用于处理结果,但不返回任何结果,只是消费future2的值并执行一些操作(例如输出结果)。 -
异常处理
CompletableFuture<Integer> future4 = CompletableFuture.supplyAsync(() -> { if (true) { throw new RuntimeException("Something went wrong"); } return 100; }).exceptionally(ex -> { System.out.println("Exception: " + ex.getMessage()); return -1; // 返回一个默认值 });通过
exceptionally方法,我们可以处理任务执行中的异常,并返回一个默认值。 -
等待所有任务完成
CompletableFuture.allOf(future1, future2, future3, future4).join();allOf用于等待多个CompletableFuture完成,join会阻塞直到所有任务完成。
5. 结果输出
运行此代码时,您可能会看到如下输出(根据线程的调度,输出的顺序可能不同):
Task 1 is running in thread: ForkJoinPool.commonPool-worker-1
Task 2 is running in thread: ForkJoinPool.commonPool-worker-2
Task 3 is running in thread: ForkJoinPool.commonPool-worker-3
Result: 20
Exception: Something went wrong
Main thread: main
6. 总结
CompletableFuture提供了更强大的异步编程能力,可以执行异步任务并组合多个任务。- 支持
thenApply,thenAccept,thenCombine,exceptionally等方法来实现结果的处理和任务的组合。 - 通过
CompletableFuture.allOf()或CompletableFuture.anyOf()可以等待多个异步任务的完成,适合并发和异步编程场景。