面试题答案
一键面试在高并发场景中,CompletableFuture
提供了几种处理异常的方式,确保即使部分任务出错,整体业务逻辑仍能尽可能正常运行。以下是处理异常的常见方法及代码示例:
- 使用
exceptionally
方法:该方法用于在任务执行过程中发生异常时提供一个替代结果。 - 使用
handle
方法:此方法可以同时处理正常结果和异常情况。
代码示例
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
public class CompletableFutureExceptionHandling {
public static void main(String[] args) {
CompletableFuture<String> task1 = CompletableFuture.supplyAsync(() -> "Task 1 completed");
CompletableFuture<String> task2 = CompletableFuture.supplyAsync(() -> {
if (Math.random() < 0.5) {
throw new RuntimeException("Task 2 failed");
}
return "Task 2 completed";
});
CompletableFuture<String> task3 = CompletableFuture.supplyAsync(() -> "Task 3 completed");
CompletableFuture<Void> allTasks = CompletableFuture.allOf(task1, task2, task3);
allTasks.join(); // 等待所有任务完成
task1.thenApply(result -> {
System.out.println("Task 1 result: " + result);
return result;
}).exceptionally(ex -> {
System.out.println("Task 1 exception: " + ex.getMessage());
return "Task 1 failed";
}).thenAccept(System.out::println);
task2.handle((result, ex) -> {
if (ex != null) {
System.out.println("Task 2 exception: " + ex.getMessage());
return "Task 2 failed";
} else {
System.out.println("Task 2 result: " + result);
return result;
}
}).thenAccept(System.out::println);
task3.thenApply(result -> {
System.out.println("Task 3 result: " + result);
return result;
}).exceptionally(ex -> {
System.out.println("Task 3 exception: " + ex.getMessage());
return "Task 3 failed";
}).thenAccept(System.out::println);
try {
allTasks.get(); // 获取所有任务的结果,如果有异常会抛出
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
}
解释
- 创建任务:创建了三个
CompletableFuture
任务,其中task2
故意设置了可能抛出异常的逻辑。 - 等待所有任务完成:使用
CompletableFuture.allOf
方法等待所有任务完成。 - 处理异常:
task1
和task3
:使用exceptionally
方法处理异常,如果任务执行成功则打印结果,否则打印异常信息并返回替代结果。task2
:使用handle
方法同时处理正常结果和异常情况,打印相应信息并返回结果或替代结果。
- 获取结果:通过
allTasks.get()
获取所有任务的结果,如果有异常会抛出,可以在try-catch
块中处理。
这样可以确保在高并发场景下,即使部分任务出错,整体业务逻辑仍能尽可能正常运行。