在Java并发编程中,CompletableFuture
是java.util.concurrent
包中的一个非常强大的类,它扩展了Future
接口,并提供了更多高级功能,如异步回调和组合操作。CompletableFuture
是一个用于异步计算的高级API,它使得编写异步代码变得更加容易和直观。
CompletableFuture的特点
- 异步编程:
CompletableFuture
支持异步编程模型,允许您定义一系列异步操作,并在操作完成后执行回调。 - 组合操作:您可以组合多个
CompletableFuture
实例,以便在它们完成时执行特定的操作。 - 异常处理:
CompletableFuture
提供了优雅的异常处理机制,使得错误传播和处理更加容易。 - 阻塞和非阻塞操作:
CompletableFuture
支持阻塞和非阻塞操作,可以在适当的时候等待计算结果。
创建CompletableFuture
CompletableFuture
可以通过多种方式创建:
-
使用静态方法:
supplyAsync(Supplier<T> supplier)
:创建一个异步计算结果的CompletableFuture
。runAsync(Runnable runnable)
:创建一个异步执行任务的CompletableFuture
。
-
使用构造器:
CompletableFuture<T>()
:创建一个空的CompletableFuture
。CompletableFuture<T>(CompletionStage<T> thenCompose)
:创建一个与给定的CompletionStage
关联的CompletableFuture
。
常用方法
CompletableFuture
提供了许多方法来处理异步操作:
-
异步操作:
thenApply(Function<T, U> function)
:当CompletableFuture
完成时,应用给定的函数。thenAccept(Consumer<T> action)
:当CompletableFuture
完成时,执行给定的消费者。thenRun(Runnable action)
:当CompletableFuture
完成时,执行给定的Runnable。
-
组合操作:
thenCombine(CompletableFuture<U> other, BiFunction<T, U, V> function)
:当两个CompletableFuture
都完成时,应用给定的双函数。thenCompose(Function<T, ? extends CompletableFuture<U>> function)
:当CompletableFuture
完成时,返回一个新的CompletableFuture
。
-
异常处理:
exceptionally(Function<Throwable, U> fn)
:当CompletableFuture
异常完成时,应用给定的函数。handle(BiFunction<T, Throwable, U> fn)
:无论CompletableFuture
是否异常完成,都会应用给定的函数。
-
阻塞操作:
get()
:阻塞直到计算完成,并返回结果。join()
:阻塞直到计算完成,并返回结果。
示例代码
下面是一个简单的示例,展示如何使用CompletableFuture
来异步计算两个数的和,并在完成后打印结果:
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
public class CompletableFutureExample {
public static void main(String[] args) {
CompletableFuture<Integer> future1 = CompletableFuture.supplyAsync(() -> 10);
CompletableFuture<Integer> future2 = CompletableFuture.supplyAsync(() -> 20);
CompletableFuture<Integer> sumFuture = future1.thenCombine(future2, (a, b) -> a + b);
sumFuture.thenAccept(sum -> System.out.println("Sum: " + sum));
try {
System.out.println("Sum (blocking): " + sumFuture.get());
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
}
在这个示例中,我们创建了两个CompletableFuture
实例,分别代表异步计算的10和20。然后,我们使用thenCombine
方法将这两个CompletableFuture
组合起来,计算它们的和。最后,我们使用thenAccept
方法来注册一个回调,当计算完成后打印结果。此外,我们也使用了get
方法来阻塞并获取计算结果。
异步回调
CompletableFuture
的强大之处在于它支持异步回调。当一个CompletableFuture
完成时,你可以注册一个回调来处理结果。例如:
CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
// 模拟耗时操作
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
return 42;
});
// 注册回调
future.thenAccept(result -> System.out.println("Result: " + result));
总结
CompletableFuture
是一个非常强大的工具,它使得异步编程变得更加容易和直观。通过使用CompletableFuture
,你可以轻松地处理异步操作、组合多个异步操作的结果,并优雅地处理异常。在编写高性能和响应式的Java应用程序时,CompletableFuture
是一个不可或缺的工具。