CompletableFuture 是 Java 8 中引入的一个重要类,它实现了 Future 接口,并且扩展了 CompletionStage 接口,提供了比传统 Future 更加丰富和灵活的功能。CompletableFuture 旨在简化异步编程模型,并且通过函数式编程的能力,使得异步代码的编写变得更加简洁和易于理解。

创建 CompletableFuture

CompletableFuture 可以通过多种方式创建,例如使用 completedFuture() 方法创建一个已完成的 CompletableFuture:

1
2
CompletableFuture<String> future = CompletableFuture.completedFuture("hello!");
assertEquals("hello!", future.get());

异步任务

对于异步任务,CompletableFuture 提供了 supplyAsyncrunAsync 方法。supplyAsync 创建一个带有返回值的异步任务,而 runAsync 则用于没有返回值的任务:

1
2
3
4
CompletableFuture<Integer> result = CompletableFuture.supplyAsync(() -> {
// 执行异步计算
return someExpensiveCalculation();
});

任务编排

CompletableFuture 支持任务之间的编排,这意味着可以轻松地组织不同任务的运行顺序、规则以及方式。例如,可以使用 thenApply 方法来等待前一个任务结束,并拿到结果后继续处理:

1
2
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> "Hello")
.thenApply(s -> s + " CompletableFuture");

异常处理

CompletableFuture 还提供了异常处理机制,例如使用 exceptionally 方法可以处理前面阶段抛出的异常:

1
2
3
CompletableFuture<String> result = CompletableFuture.supplyAsync(() -> {
throw new RuntimeException("Oops!");
}).exceptionally(ex -> "Default value");

组合多个任务

CompletableFuture 支持多个任务的组合处理,例如 thenCombine 可以将两个 CompletableFuture 的结果合并:

1
2
3
CompletableFuture<String> first = CompletableFuture.supplyAsync(() -> "Hello");
CompletableFuture<String> second = CompletableFuture.supplyAsync(() -> "World");
CompletableFuture<String> combined = first.thenCombine(second, (f1, f2) -> f1 + " " + f2);

自定义线程池

默认情况下,CompletableFuture 使用 ForkJoinPool.commonPool() 作为执行异步任务的线程池,但也可以指定其他线程池:

1
2
ExecutorService executor = Executors.newFixedThreadPool(10);
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> "Hello", executor);

总结

通过使用 CompletableFuture,开发人员可以更方便地管理异步任务,减少回调地狱的问题,并且能够以声明式的方式来编写异步代码。这对于提高代码的可读性和可维护性是非常有益的。此外,由于 CompletableFuture 的灵活性,它也适用于多种并发编程场景,如Web服务调用、数据库访问等。