面试题答案
一键面试设计思路
- 异常捕获与处理:在
thenApplyAsync
链式调用中,使用exceptionally
方法来捕获异常。这样可以在每个异步操作抛出异常时,及时捕获并进行处理,避免异常中断整个链式调用。 - 异常传递:在
exceptionally
处理逻辑中,可以选择返回一个默认值或者继续抛出异常,以便上层调用者进一步处理。 - 性能优化:合理使用线程池,减少线程创建和销毁带来的开销。避免不必要的线程切换,尽量让任务在同一个线程池中的线程上执行。
Java代码
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
public class CompletableFutureExceptionHandling {
private static final ExecutorService executor = Executors.newFixedThreadPool(5);
public static void main(String[] args) {
CompletableFuture.supplyAsync(() -> {
if (Math.random() < 0.5) {
throw new RuntimeException("模拟异常1");
}
return "初始结果";
}, executor)
.thenApplyAsync(result -> {
if (Math.random() < 0.5) {
throw new IllegalArgumentException("模拟异常2");
}
return result + " 处理后";
}, executor)
.thenApplyAsync(result -> {
if (Math.random() < 0.5) {
throw new NullPointerException("模拟异常3");
}
return result + " 再次处理后";
}, executor)
.exceptionally(ex -> {
System.out.println("捕获到异常: " + ex.getMessage());
// 这里可以选择返回默认值或者继续抛出异常
return "默认结果";
})
.thenAcceptAsync(System.out::println, executor);
// 关闭线程池
executor.shutdown();
}
}
在上述代码中:
CompletableFuture.supplyAsync
开启一个异步任务,并在其中模拟可能抛出的异常。- 每个
thenApplyAsync
方法同样模拟可能抛出不同类型异常的操作。 exceptionally
方法捕获链式调用过程中抛出的异常,并进行处理,这里简单打印异常信息并返回默认值。- 使用
ExecutorService
线程池来执行异步任务,通过合理设置线程池大小来优化性能,同时在程序结束时关闭线程池。