java 8 引入的 completablefuture 通过链式调用方法实现依赖执行,核心在于利用前一个任务的完成状态触发后续任务。最常用的方式是使用 thenapply() 处理同步转换,或使用 thenaccept() 处理异步副作用。若需等待多个前置任务全部完成再执行下一步,应使用 allof() 组合多个 future 对象。

thenApply() 与 thenAccept() 的区别是什么
thenApply() 用于有返回值的转换操作,而 thenAccept() 用于无返回值的消费操作。前者接收一个 Function 接口,后者接收一个 Consumer 接口。在依赖执行中,选择哪种方法取决于当前步骤是否需要将结果传递给下一个环节。

import java.util.concurrent.CompletableFuture;
public class DependencyExample {
public static void main(String[] args) throws Exception {
// 模拟第一个耗时任务
CompletableFuture<string> step1 = CompletableFuture.supplyAsync(() -> {
System.out.println("Step 1: Fetching data...");
return "Data";
});
// 依赖 Step 1 的结果进行转换 (有返回值)
CompletableFuture<integer> step2 = step1.thenApply(data -> {
System.out.println("Step 2: Processing data... " + data);
return data.length();
});
// 依赖 Step 2 的结果进行消费 (无返回值)
step2.thenAccept(length -> {
System.out.println("Step 3: Result length is: " + length);
});
// 阻塞主线程以等待所有任务完成
CompletableFuture.allOf(step1, step2).join();
}
}</integer></string>
如何并行执行多个独立任务并汇总结果
当存在多个互不依赖但都需要在某个阶段完成后统一处理的子任务时,可以使用 CompletableFuture.allOf()。该方法接收一组 CompletableFuture 对象,返回一个新的 CompletableFuture,只有当所有传入的任务都完成时,该新 Future 才会完成。这种方式避免了手动轮询或嵌套依赖,提高了并发效率。

import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
public class ParallelDependency {
public static void main(String[] args) throws Exception {
// 创建三个独立的异步任务
CompletableFuture<string> task1 = CompletableFuture.supplyAsync(() -> "Result 1");
CompletableFuture<string> task2 = CompletableFuture.supplyAsync(() -> "Result 2");
CompletableFuture<string> task3 = CompletableFuture.supplyAsync(() -> "Result 3");
// 等待所有任务完成
CompletableFuture.allOf(task1, task2, task3).join();
// 获取每个任务的结果并汇总
String summary = IntStream.range(0, 3)
.mapToObj(i -> {
try {
if (i == 0) return task1.get();
if (i == 1) return task2.get();
return task3.get();
} catch (Exception e) {
return "Error";
}
})
.collect(Collectors.joining(", "));
System.out.println("Summary: " + summary);
}
}</string></string></string>
如果依赖的前置任务抛出异常会怎样
如果前置任务在执行过程中抛出未捕获的异常,后续的 thenApply 或 thenAccept 将不会执行,而是直接进入异常处理流程。此时,可以通过 exceptionally() 方法来提供默认值或记录日志,从而保证程序的健壮性。如果不处理异常,最终调用 get() 或 join() 时会抛出 ExecutionException。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











