利用 ThreadFactory 统一处理异常
线程池的使用必不可少,使用无返回值 execute() 方法时,线程执行发生异常的话,需要记录日志,方便回溯,一般做法是在线程执行方法内 try/catch 处理 ,如下所示:
@Test
public void thread() {
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(5, 10, 60, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(100));
threadPoolExecutor.execute(() -> {
try {
log.info(Thread.currentThread().getName());
int i = (1 / 0);
} catch (Exception e) {
log.error("发生异常 => {}", e);
}
});
try {
Thread.sleep(10000000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
因为线程池一般情况下,都不会在一个项目里创建多个线程池,那么随着线程池在项目中多个地方提交任务时,使用 try/catch 进行异常捕获和记录,对于整个线程池管理非常不方便。我们可以通过利用 ThreadFactory ,在创建线程时,指定 setUncaughtExceptionHandler 异常处理方法,这样就可以做到全局处理异常。
@Test
public void test() {
ThreadFactory threadFactory = r -> {
Thread thread = new Thread(r);
thread.setName("testThread");
thread.setUncaughtExceptionHandler((t, err) -> {
log.info(t.getName());
log.error("err => {}", err);
});
return thread;
};
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(5, 10, 60, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(100), threadFactory);
// threadPoolExecutor.setThreadFactory(threadFactory);
threadPoolExecutor.execute(() -> {
log.info(Thread.currentThread().getName());
int i = (1 / 0);
});
try {
Thread.sleep(10000000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}