Spring Boot 创建线程池

线程池使用约定

首先,线程在我们程序员的世界里可以说是无处不在,简单来说,线程池便是将线程进行池化,方便对有限的线程资源进行统一调度和管理。在 Java Web 的项目中,我们队线程池有一些这样的使用约定。

什么情况下使用线程池

执行任务的数量极大

单个任务执行的时间很短,并且可以多个并行执行时

执行的任务需要限流排队时

需要并行执行任务时

……

太多了数不过来,也有时候是上面多个情况的组合。

禁止使用 Executors 创建线程池

这条肯定不是规范,而是一条编码规约(特定规范的约定),为了避免线程池参数不规范从而导致的内存溢出( OOM)问题。

主要还是由于 Executors 创建线程池对象的方法,主要有三种:

Executors#newCachedThreadPool => 创建可缓存的线程池

Executors#newSingleThreadExecutor => 创建单线程的线程池

Executors#newFixedThreadPool => 创建固定长度的线程池

其中 CachedThreadPool 的最大线程数是 Integer.MAX_VALUE,可以认为是无限的,这就很容易失控,导致线程堆积,CPU 占用 100% 后的 OOM。

第二种 newSingleThreadExecutor 线程池是单线程,加上一个 workQueue 队列(使用 LinkedBlockingQueue),也有不完善的问题,如果单线程执行太慢或者发生阻塞,队列里面的任务将会持续堆积,知道发生 OOM 异常。对,看出来了,这个线程池没有队列的拒绝策略功能。

第三种 newFixedThreadPool 固定长度线程池中,队列也是一个无界队列 LinkedBlockingQueue,所以在资源有限的情况下,没有线程队列的拒绝策略是很可怕的。

这里只是简单说一些,如果想了解详情,可以自行搜索圈子内的一篇文章《为什么阿里巴巴要禁用 Executors 创建线程池?》。

结论

就是使用禁止使用 Executors 去创建线程池,推荐通过自己创建 ThreadPoolExecutor 的方式来使用线程池。

使用 Spring Boot 创建线程池

猜你喜欢

转载自www.cnblogs.com/iebush/p/12939433.html