面试题答案
一键面试设计思路
- 统一异常处理入口:利用
CompletableFuture
的exceptionally
方法来捕获任务链中的异常。这个方法会在CompletableFuture
发生异常时被调用,从而提供一个统一的异常处理入口。 - 区分异常类型:在
exceptionally
方法中,通过instanceof
关键字区分业务异常和系统异常,以便进行不同的处理。 - 恢复执行逻辑:对于业务异常,可以根据业务需求进行特定处理,如记录日志、返回默认值或进行补偿操作。对于系统异常,除了记录日志外,可能需要采取更激进的措施,如终止整个任务链或进行系统级别的恢复操作。
- 减少资源浪费和性能损耗:避免在异常处理过程中进行不必要的计算或I/O操作,尽量保持处理逻辑的简洁高效。在捕获异常后快速做出响应,避免长时间阻塞或资源占用。
关键代码片段
import java.util.concurrent.CompletableFuture;
// 假设这是业务异常类
class BusinessException extends RuntimeException {
public BusinessException(String message) {
super(message);
}
}
// 假设这是系统异常类
class SystemException extends RuntimeException {
public SystemException(String message) {
super(message);
}
}
public class CompletableFutureExceptionHandling {
public static void main(String[] args) {
CompletableFuture.supplyAsync(() -> {
// 模拟可能抛出业务异常的任务
if (Math.random() < 0.5) {
throw new BusinessException("业务异常发生");
}
return "任务1完成";
})
.thenApply(result -> {
// 模拟依赖前一个任务结果的任务,可能抛出系统异常
if (Math.random() < 0.5) {
throw new SystemException("系统异常发生");
}
return result + " -> 任务2完成";
})
.exceptionally(ex -> {
if (ex instanceof BusinessException) {
// 处理业务异常
System.err.println("捕获到业务异常: " + ex.getMessage());
return "业务异常处理结果";
} else if (ex instanceof SystemException) {
// 处理系统异常
System.err.println("捕获到系统异常: " + ex.getMessage());
// 这里可以进行系统级别的处理,如终止任务链等
return "系统异常处理结果";
}
return "未知异常处理结果";
})
.thenAccept(System.out::println);
}
}
在上述代码中:
supplyAsync
方法启动一个异步任务,这个任务可能抛出BusinessException
。thenApply
方法基于前一个任务的结果进行操作,并且可能抛出SystemException
。exceptionally
方法捕获整个任务链中的异常,通过instanceof
区分异常类型并进行相应处理。最终的处理结果会传递给thenAccept
方法进行输出。