在Java开发中,线程池的使用必不可少,使用无返回值 execute() 方法时,线程执行发生异常的话,需要记录日志,方便回溯,一般做法是在线程执行方法内 try/catch 处理,如下:
让客户满意是我们工作的目标,不断超越客户的期望值来自于我们对这个行业的热爱。我们立志把好的技术通过有效、简单的方式提供给客户,将通过不懈努力成为客户在信息化领域值得信任、有价值的长期合作伙伴,公司提供的服务项目有:域名申请、网站空间、营销软件、网站建设、南涧网站维护、网站推广。@Test
public void test() throws Exception {
ThreadPoolExecutor threadPoolExecutor =
new ThreadPoolExecutor(5, 10, 60,
TimeUnit.SECONDS,
new ArrayBlockingQueue<>(100000));
Futuresubmit = threadPoolExecutor.execute(() ->{
try {
int i = 1 / 0;
return i;
} catch (Exception e) {
log.error(e.getMessage(), e);
return null;
}
});
}
但是当线程池调用方法很多时,那么每个线程执行方法内都要 try/catch
处理,这就不优雅了,其实ThreadPoolExecutor
类还支持传入 ThreadFactory
参数,自定义线程工厂,在创建 thread
时,指定 setUncaughtExceptionHandler
异常处理方法,这样就可以做到全局处理异常了,代码如下:
ThreadFactory threadFactory = r ->{
Thread thread = new Thread(r);
thread.setUncaughtExceptionHandler((t, e) ->{
// 记录线程异常
log.error(e.getMessage(), e);
});
return thread;
};
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(5, 10, 60,
TimeUnit.SECONDS, new ArrayBlockingQueue<>(100000),
threadFactory);
threadPoolExecutor.execute(() ->{
log.info("---------------------");
int i = 1 / 0;
});
线程池决绝策略设置错误导致业务接口执行超时先介绍下线程池得四种决绝策略
如下是一个线上业务接口使用得线程池配置,决绝策略采用 CallerRunsPolicy
// 某个线上线程池配置如下
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
50, // 最小核心线程数
50, // 大线程数,当队列满时,能创建的大线程数
60L, TimeUnit.SECONDS, // 空闲线程超过核心线程时,回收该线程的大等待时间
new LinkedBlockingQueue<>(5000), // 阻塞队列大小,当核心线程使用满时,新的线程会放进队列
new CustomizableThreadFactory("task"), // 自定义线程名
new ThreadPoolExecutor.CallerRunsPolicy() // 线程执行的拒绝策略
);
在某些情况下,子线程任务调用第三方接口超时,导致核心线程数、大线程数占满、阻塞队列占满的情况下执行拒绝策略时,由于使用 CallerRunsPolicy
策略,导致业务线程执行子任务时继续超时,进而导致接口执行异常,这种情况下,考虑到子线程任务得重要性,不是很重要得话,可以使用 DiscardPolicy
策略,要是很重要,可以发送到消息队列中持久化子线程任务数据待后续处理
你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧