面试题答案
一键面试import java.util.concurrent.*;
public class AsyncTaskSequence {
private static final int CORE_POOL_SIZE = 3;
private static final int MAX_POOL_SIZE = 5;
private static final long KEEP_ALIVE_TIME = 10L;
private static final TimeUnit TIME_UNIT = TimeUnit.SECONDS;
private static final int QUEUE_CAPACITY = 10;
public static void main(String[] args) {
ThreadPoolExecutor executor = new ThreadPoolExecutor(
CORE_POOL_SIZE,
MAX_POOL_SIZE,
KEEP_ALIVE_TIME,
TIME_UNIT,
new ArrayBlockingQueue<>(QUEUE_CAPACITY));
CompletableFuture.supplyAsync(() -> {
try {
return taskA();
} catch (Exception e) {
throw new CompletionException(e);
}
}, executor)
.thenApplyAsync(resultA -> {
try {
return taskB(resultA);
} catch (Exception e) {
throw new CompletionException(e);
}
}, executor)
.thenApplyAsync(resultB -> {
try {
return taskC(resultB);
} catch (Exception e) {
throw new CompletionException(e);
}
}, executor)
.exceptionally(ex -> {
System.out.println("任务执行出错: " + ex.getMessage());
return null;
})
.thenRun(() -> executor.shutdown());
}
private static String taskA() throws Exception {
// 模拟任务A执行
System.out.println("任务A开始执行");
TimeUnit.SECONDS.sleep(2);
System.out.println("任务A执行完成");
return "任务A的结果";
}
private static String taskB(String resultA) throws Exception {
// 模拟任务B执行,依赖任务A的结果
System.out.println("任务B开始执行,依赖任务A的结果: " + resultA);
TimeUnit.SECONDS.sleep(2);
System.out.println("任务B执行完成");
return "任务B的结果";
}
private static String taskC(String resultB) throws Exception {
// 模拟任务C执行,依赖任务B的结果
System.out.println("任务C开始执行,依赖任务B的结果: " + resultB);
TimeUnit.SECONDS.sleep(2);
System.out.println("任务C执行完成");
return "任务C的结果";
}
}
- 线程池设置:
- 使用
ThreadPoolExecutor
创建一个自定义线程池,设置核心线程数为3,最大线程数为5,线程存活时间为10秒,任务队列容量为10。
- 使用
- 任务执行:
- 使用
CompletableFuture.supplyAsync
方法在自定义线程池中执行任务A。如果任务A执行出错,将异常包装为CompletionException
抛出。 - 使用
thenApplyAsync
方法依赖任务A的结果执行任务B,同样如果任务B执行出错,将异常包装为CompletionException
抛出。 - 使用
thenApplyAsync
方法依赖任务B的结果执行任务C,若任务C执行出错,也将异常包装为CompletionException
抛出。
- 使用
- 异常处理:
- 使用
exceptionally
方法捕获整个任务链中出现的异常,并打印错误信息。
- 使用
- 线程池关闭:
- 使用
thenRun
方法在任务链执行完成后关闭线程池。
- 使用
这样可以确保在异步任务按顺序执行的同时,通过自定义线程池提高效率,并在任务执行出错时进行适当的异常处理,保证整个流程的健壮性。