面试题答案
一键面试并行策略
使用 CompletableFuture
的 allOf
方法来并行执行多个任务。allOf
方法会等待所有给定的 CompletableFuture
都完成,这样可以充分利用多核 CPU 的优势,提高执行效率。
结果合并方法
使用 thenApply
方法在所有任务完成后对结果进行合并。可以通过遍历每个 CompletableFuture
的结果列表,然后将所有结果累加起来得到总的结果。
异常处理方式
为每个 CompletableFuture
设置 exceptionally
方法来处理单个任务的异常。如果任何一个任务抛出异常,exceptionally
方法会捕获异常并返回一个特殊的错误标识。同时,在合并结果时检查是否有任务返回了错误标识,如果有则直接返回错误标识,而不进行结果合并。
代码实现
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
public class CompletableFutureExample {
// 模拟任务执行方法
private static CompletableFuture<Integer> processElement(int num) {
return CompletableFuture.supplyAsync(() -> {
// 模拟一些处理,这里简单返回 num * 2
return num * 2;
});
}
public static void main(String[] args) {
List<Integer> numbers = List.of(1, 2, 3, 4, 5);
List<CompletableFuture<Integer>> futures = new ArrayList<>();
// 创建并启动所有任务
for (int num : numbers) {
futures.add(processElement(num)
.exceptionally(ex -> {
// 处理单个任务的异常
System.out.println("Task failed: " + ex.getMessage());
return -1; // 特殊错误标识
}));
}
// 等待所有任务完成并合并结果
CompletableFuture<Void> allFutures = CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]));
CompletableFuture<Integer> resultFuture = allFutures.thenApply(v -> {
int total = 0;
boolean hasError = false;
for (CompletableFuture<Integer> future : futures) {
try {
int result = future.get();
if (result == -1) {
hasError = true;
break;
}
total += result;
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
return hasError? -1 : total;
});
// 获取最终结果
try {
int result = resultFuture.get();
if (result == -1) {
System.out.println("Overall operation failed");
} else {
System.out.println("Total result: " + result);
}
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
}
选择这样实现的原因
- 并行策略:
allOf
方法简单高效,能够方便地管理多个并行任务,并且等待所有任务完成,适合这种需要所有任务结果进行后续操作的场景。 - 结果合并方法:
thenApply
方法在所有任务完成后进行操作,符合需求。通过遍历结果列表进行累加,逻辑清晰易懂。 - 异常处理方式:为每个任务设置
exceptionally
方法可以确保单个任务失败不会影响其他任务的执行,并且能够及时捕获并处理异常。在合并结果时检查错误标识,保证整个合并操作能够正确处理失败情况。