keepAliveTime为0以及队列太小导致ThreadPoolExecutor不断创建新线程

本文产生原因

群友问题:

使用ThreadPoolExecutor实现固定大小的线程池,但是程序跑一段时间后,就会重新创建新的线程,求问有人遇到过这个问题吗?
在这里插入图片描述

询问工作队列,最大线程数,超时时间参数值设置

猜测

队列太小。容易导致队列满后,启动非核心线程。怀疑 keepAliveTime为0,导致线程池的线程runWorker期间,调用getTask不等待。

线程池
new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, timeUnit, workQueue,Executors.defaultThreadFactory(), defaultHandler);
execute提交任务时:
当execute时,线程小于corePoolSize,则addWorker(firstTask,true)创建新线程。
当线程数量 大于核心数量corePoolSize后,则将任务入队。
当workQueue到达最大数量时,继续创建线程直到线程数量大于maximumPoolSize
当线程数量大于maximumPoolSize后,执行拒绝策略defaultHandler
TERMINALTED:当非core线程空闲时间(getTask)超过keepAliveTime, timeUnit指定的时间后,则退出。
threadPoolExecutor允许核心线程退出,类似于5.
线程池中的线程何时死亡?

源码

查看源码,【keepAliveTime为0,会在队列为空的时候不等待】,返回0.(这里是ArrayBlockingQueue的实现)

在这里插入图片描述
在这里插入图片描述

测试

在这里插入图片描述

jvisualVM 查看线程

现象:能看见在不断创建线程。应该有一个核心线程,但所有线程的name都在变化。

在这里插入图片描述

结论:

  1. keepAliveTime为0以及队列太小导致ThreadPoolExecutor不断创建新线程
  2. 核心线程并不指的最先创建的那几个。 而是指当前少于core线程就算核心线程。
  3. keepAliveTime为0导致非core线程运行完后就休眠。查看ThreadPoolExecutor#getTask

线程池中的线程何时死亡?

ThreadPoolExecutor类在创建线程池时提供了三个参数来控制任务队列:corePoolSize、maximumPoolSize和workQueue。 其中,workQueue参数用于指定任务队列的类型。ThreadPoolExecutor支持以下四种任务队列类型: 1. 直接提交队列(SynchronousQueue):这是一个没有容量的队列,每个插入操作都必须等待一个相应的删除操作,因此这种任务队列类型会将任务直接提交给线程池中的线程来处理,而不会将任务保存在队列中。 2. 有界任务队列(ArrayBlockingQueue):这是一个容量固定的队列,当线程池中的线程数达到corePoolSize时,的任务将被放入该队列,直到队列满。此时,如果继续有的任务提交,线程池创建额外的线程来处理这些任务,直到线程数达到maximumPoolSize为止。 3. 无界任务队列(LinkedBlockingQueue):这是一个容量无限的队列,当线程池中的线程数达到corePoolSize时,的任务将被放入该队列,不会有任务被拒绝。此时,如果继续有的任务提交,线程池不会创建额外的线程来处理这些任务,而是让这些任务一直等待到有空闲的线程为止。 4. 优先任务队列(PriorityBlockingQueue):这是一个基于优先级的无限容量队列,可以根据任务的优先级来决定任务的执行顺序。 在创建ThreadPoolExecutor对象时,可以通过第三个参数workQueue来指定任务队列类型,例如: ``` ThreadPoolExecutor executor = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(queueSize)) ``` 这里使用的是有界任务队列ArrayBlockingQueue,队列的容量为queueSize。如果要使用其他类型的任务队列,只需要将new ArrayBlockingQueue<Runnable>(queueSize)替换为相应的队列类型即可。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值