ThreadPoolExecutor中的异常捕获
Contents
现象
线上服务日志发现有中断(即日志前面有打印, 但后面的日志没打印), 并且又没有异常信息输出.
原因
代码示例
private static final ThreadPoolTaskExecutor THREAD_POOL_TASK_EXECUTOR = new ThreadPoolTaskExecutor();
static {
THREAD_POOL_TASK_EXECUTOR.setQueueCapacity(10000);
THREAD_POOL_TASK_EXECUTOR.setDaemon(true);
THREAD_POOL_TASK_EXECUTOR.setThreadNamePrefix("global-%d");
THREAD_POOL_TASK_EXECUTOR.setRejectedExecutionHandler((r, executor) -> {
Loggers.ERROR_LOG.info("加入任务被拒绝: {}", r);
//自动执行
r.run();
});
THREAD_POOL_TASK_EXECUTOR.setThreadFactory(r -> {
final Thread thread = new Thread(r);
thread.setUncaughtExceptionHandler((t, e) -> Loggers.ERROR_LOG.error(e.getMessage(), e));
return thread;
});
THREAD_POOL_TASK_EXECUTOR.setWaitForTasksToCompleteOnShutdown(true);
THREAD_POOL_TASK_EXECUTOR.initialize();
}
@PreDestroy
public void destroy() {
THREAD_POOL_TASK_EXECUTOR.shutdown();
}
public void submit(Runnable task) {
THREAD_POOL_TASK_EXECUTOR.submit(task);
}
原来是 ThreadPoolTaskExecutor.submit
方法, 这个方法的返回值是 Future
类型. 默认情况下, 它只有在调用 get()
方法时才会返回处理结果以及异常检查.
处理
调用
get()
方法. 但这里显然不太符合我们的要求. 我们是想它异步处理的, 并不需要等待它的结果.将
submit()
修改为execute()