在 java 中组合多个 completablefuture 主要依赖其提供的链式 api,如 thenapply、thenaccept、thencombine 和 allof。若需串行处理结果,使用 thencompose;若需并行等待所有任务完成,使用 allof 配合 join 获取结果集;若需合并两个独立任务的结果,使用 thencombine。这些方法允许开发者在不阻塞线程的情况下灵活编排异步逻辑。

如何串行转换前一个任务的结果?
要串行转换前一个任务的结果,应使用 thenCompose 或 thenApply。thenApply 适用于同步转换,将上一个任务的返回值作为参数传入当前函数;thenCompose 适用于异步转换,当前函数返回一个新的 CompletableFuture,从而形成链式调用。这种方式能确保前一个任务完成后才执行后续逻辑,且异常会沿链传播。

import java.util.concurrent.CompletableFuture;
public class ChainExample {
public static void main(String[] args) throws Exception {
CompletableFuture<string> step1 = CompletableFuture.supplyAsync(() -> "Hello");
// 使用 thenApply 进行同步转换
CompletableFuture<string> step2 = step1.thenApply(s -> s + " World");
// 使用 thenCompose 进行异步转换
CompletableFuture<string> step3 = step2.thenCompose(s ->
CompletableFuture.supplyAsync(() -> s + "!"));
System.out.println(step3.join()); // 输出: Hello World!
}
}</string></string></string>
如何并行等待多个任务并收集结果?
当需要并行执行多个独立任务并在全部完成后收集结果时,应使用 allOf。allOf 接收一组 CompletableFuture 对象,返回一个新的 CompletableFuture。该新任务在所有输入任务都完成后完成,但不会直接提供结果。因此,需要在 allOf().join() 之后,通过遍历原始任务列表并调用各自的 join() 方法来获取具体结果。这种方法适合批量处理场景,如并发查询数据库或远程服务。

import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;
public class ParallelExample {
public static void main(String[] args) throws Exception {
List<completablefuture>> futures = Arrays.asList(
CompletableFuture.supplyAsync(() -> 1),
CompletableFuture.supplyAsync(() -> 2),
CompletableFuture.supplyAsync(() -> 3)
);
CompletableFuture<void> allDone = CompletableFuture.allOf(
futures.toArray(new CompletableFuture[0])
);
allDone.join(); // 等待所有任务完成
List<integer> results = futures.stream()
.map(CompletableFuture::join)
.collect(Collectors.toList());
System.out.println(results); // 输出: [1, 2, 3]
}
}</integer></void></completablefuture>
如果某个任务抛出异常,其他任务会受影响吗?
如果某个任务抛出异常,默认情况下它会中断当前链路的后续操作,但不会影响其他并行启动的独立任务。CompletableFuture 的设计是隔离异常的:每个 CompletableFuture 实例的状态是独立的。当一个任务失败时,其后续的 thenApply 或 thenCompose 不会被执行,除非使用了 exceptionally 或 handle 方法进行异常恢复。对于 allOf 场景,即使其中一个任务失败,allOf 仍会等待所有任务完成(包括失败的),但在获取结果时调用 join() 会抛出 CompletionException。因此,异常处理需要在每个任务或链路末端显式定义策略。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











