线程池异常处理
背景:有时候我们把一些业务逻辑丢在线程池处理,本身的业务方法又没有打印日志,导致这个方法执行过程中是否出错了根本不知道,异常信息基本丢失,问题不好排除。
方式一 简单粗暴 try catch 执行的方法
@Test
public void testThreadException(){
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(5,5,2,
TimeUnit.SECONDS,new LinkedBlockingDeque<>(20)
,new ThreadPoolExecutor.CallerRunsPolicy());
for (int i = 0;i < 5;i++){
int finalI = i;
threadPoolExecutor.execute(()-> log.info("{}",test(finalI)));
}
threadPoolExecutor.shutdown();
}
public int test(int i){
try {
return 2/i;
}catch (Exception e){
log.error("线程{}出错了",Thread.currentThread().getName(),e);
return i;
}
}
}
方式二 重写一下 线程工厂中给线程设置uncaughtExceptionHandler
@Test
public void testThreadException(){
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(5,5,2,
TimeUnit.SECONDS,new LinkedBlockingDeque<>(20),
threadFactory -> {
Thread t = new Thread(threadFactory);
// 获取线程池中的异常
t.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread t, Throwable e) {
// 对异常进行处理
log.error("线程{}出错了",t.getName(),e);
}
});
return t;
}
,new ThreadPoolExecutor.CallerRunsPolicy());
for (int i = 0;i < 5;i++){
int finalI = i;
threadPoolExecutor.execute(()-> log.info("{}",test(finalI)));
}
threadPoolExecutor.shutdown();
}
public int test(int i){
return 2/i;
}
总结:方式二 更加好,可以统一定义好,这样项目里面都用公用的线程池, 可以防止有些方法 异常日志丢失了 造成排错困难。
elk
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】