框架原理java

Java线程池使用的注意事项

2019-01-19  本文已影响86人  十毛tenmao

项目中使用的线程池的地方很多,一直以来感觉对它的参数已经掌握的很好了,但是遇到几次问题之后才发现欠缺的这么多

遇到的坑

任务进入了队列,线程还在执行之前的任务。本质原因是对线程和队列的优先级认识不深刻,有一种错觉以为是所有线程都忙的时候才进入任务队列。实际上相反,是队列满的时候才会新建线程(线程数大于core size时)。

一般情况下,代码中只会去捕捉RuntimeException,如果抛出Error则会导致线程退出,而异常信息又没有拿到。最佳的解决办法是给线程池设置UncaughtExceptionHandler

回顾线程池重要的配置

线程池参数

任务提交时,判断的顺序为 corePoolSize --> workQueue --> maximumPoolSize。

这个顺序一定要弄错了

拒绝策略

RejectedExecutionHandler

默认是抛出异常,除非想得特别清楚,不然轻易不要使用其他3种策略

内置的四种线程池

这4个线程池都可能存在问题,不建议直接使用,建议使用自定义参数的线程池

如何优雅地关闭

线程池状态

线程池状态变换图

上图来自 深入理解Java线程池:ThreadPoolExecutor

优雅关闭方式

// 线程池进入SHUTDOWN状态,停止接受新的任务
executorService.shutdown();
// 等待线程池任务完成
executorService.awaitTermination(30, TimeUnit.SECONDS);

在Spring中,如果线程池作为其他Bean中的属性,则需要在Bean的destroy时,关闭线程池

@PreDestroy
public void destroy() {
    executorService.shutdown();
    executorService.awaitTermination(30, TimeUnit.SECONDS);
}

注意事项

最佳实践

参考

上一篇 下一篇

猜你喜欢

热点阅读