面试题答案
一键面试设计思路
- 异常处理:利用
CompletableFuture
的exceptionally
方法,针对不同类型的异常创建多个CompletableFuture
分支来处理异常,确保异常不会中断整个任务链。通过自定义异常类型或者使用instanceof
判断异常类型,为每种异常类型提供专门的处理逻辑。 - 执行顺序优化:分析业务逻辑,确定哪些任务可以并行执行。使用
CompletableFuture.allOf
或CompletableFuture.anyOf
方法将可以并行的任务包装起来,以提高执行效率。同时,对于有依赖关系的任务,按照依赖顺序正确构建任务链。
核心代码示例及注释
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
// 自定义异常类型
class CustomException extends Exception {
public CustomException(String message) {
super(message);
}
}
public class CompletableFutureTaskChain {
public static void main(String[] args) {
CompletableFuture.supplyAsync(() -> {
// 模拟异步任务,可能抛出异常
if (Math.random() < 0.5) {
throw new CustomException("自定义异常发生");
}
return "任务1执行结果";
})
.thenApply(result -> {
// 任务2依赖任务1的结果
System.out.println("任务2接收到任务1结果: " + result);
return "任务2执行结果";
})
.exceptionally(ex -> {
// 处理自定义异常
if (ex instanceof CustomException) {
System.out.println("处理自定义异常: " + ex.getMessage());
return "自定义异常处理结果";
} else {
// 处理其他异常
System.out.println("处理其他异常: " + ex.getMessage());
return "其他异常处理结果";
}
})
.thenApply(result -> {
// 任务3无论前面是否有异常,都会执行
System.out.println("任务3接收到结果: " + result);
return "任务3执行结果";
})
.thenRun(() -> {
System.out.println("任务链执行完毕");
})
.join();
}
}
代码说明
- 自定义异常:定义了
CustomException
用于模拟业务中的特定异常。 - 任务链构建:
supplyAsync
启动第一个异步任务,该任务有一定概率抛出CustomException
。thenApply
方法构建依赖前一个任务结果的后续任务。exceptionally
方法捕获并处理异常,针对不同类型的异常进行不同处理。- 后续的
thenApply
和thenRun
确保无论前面是否有异常,任务链都能继续执行到最后。
- 执行优化:在更复杂场景下,如果有可以并行执行的任务,可以将其包装在
CompletableFuture.allOf
中,例如:
CompletableFuture<String> taskA = CompletableFuture.supplyAsync(() -> "任务A结果");
CompletableFuture<String> taskB = CompletableFuture.supplyAsync(() -> "任务B结果");
CompletableFuture<Void> allTasks = CompletableFuture.allOf(taskA, taskB);
allTasks.join();
try {
String resultA = taskA.get();
String resultB = taskB.get();
// 使用结果继续后续任务
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
这里 taskA
和 taskB
并行执行,allOf
等待所有任务完成,然后获取结果继续后续任务。