使用execute方法提交任务捕获异常
- 直接捕获:在任务的
run
方法内部进行异常捕获。
Runnable task = () -> {
try {
// 任务逻辑
} catch (Exception e) {
// 异常处理
}
};
ExecutorService executorService = Executors.newFixedThreadPool(10);
executorService.execute(task);
- 通过UncaughtExceptionHandler:
- 实现
Thread.UncaughtExceptionHandler
接口。
- 为线程池中的线程设置该处理器。
class MyUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler {
@Override
public void uncaughtException(Thread t, Throwable e) {
// 异常处理
}
}
ExecutorService executorService = Executors.newFixedThreadPool(10);
((ThreadPoolExecutor) executorService).getThreadFactory().newThread(() -> {}).setUncaughtExceptionHandler(new MyUncaughtExceptionHandler());
Runnable task = () -> {
// 任务逻辑,不捕获异常
};
executorService.execute(task);
使用submit方法提交任务捕获异常
- 通过Future获取结果时捕获:
ExecutorService executorService = Executors.newFixedThreadPool(10);
Callable<Integer> task = () -> {
// 任务逻辑,可能抛异常
return 1;
};
Future<Integer> future = executorService.submit(task);
try {
Integer result = future.get();
} catch (InterruptedException | ExecutionException e) {
if (e instanceof ExecutionException) {
Throwable cause = e.getCause();
// 处理任务中抛出的异常
}
}
自定义线程池拒绝策略中处理异常
- 关联:
- 常规提交任务处理异常是针对单个任务执行过程中的异常。
- 自定义线程池拒绝策略处理异常是在任务因线程池已满等原因无法被接受执行时的异常处理,两者都是为了保障系统在异常情况下的稳定性。
- 区别:
- 常规提交任务处理异常:主要关注任务本身执行逻辑中的异常,确保任务内部错误得到妥善处理,保证单个任务的正确执行。
- 自定义线程池拒绝策略处理异常:关注线程池整体状态导致任务无法提交执行的情况,如线程池队列已满且最大线程数已达到上限等,目的是在这种系统级异常情况下做出合理决策,如记录日志、抛出特定异常等,以保障线程池和整个应用的稳定性。
例如,自定义拒绝策略可以这样实现:
class MyRejectedExecutionHandler implements RejectedExecutionHandler {
@Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
try {
// 可以尝试将任务放入其他队列或做特殊处理
} catch (Exception e) {
// 处理因拒绝任务而产生的异常
}
}
}
ThreadPoolExecutor executorService = new ThreadPoolExecutor(
10, 20, 10, TimeUnit.SECONDS,
new ArrayBlockingQueue<>(5),
new MyRejectedExecutionHandler());