线程池动态调整线程数

领导要动态实时调整任务的线程数,这真的是个什么烂需求,线程数不是应该根据cpu资源来评估调的最优值吗,但是领导既然说了,硬着头皮也得弄啊,还是具体研究一下,不能做也得给出个理由啊...

按照JDK文档的描述,

  • 如果池中的实际线程数小于corePoolSize,无论是否其中有空闲的线程,都会给新的任务产生新的线程
  • 如果池中的线程数>corePoolSize and <maximumPoolSize,而又有空闲线程,就给新任务使用空闲线程,如没有空闲线程,则产生新线程
  • 如果池中的线程数=maximumPoolSize,则有空闲线程使用空闲线程,否则新任务放入workQueue。(线程的空闲只有在workQueue中不再有任务时才成立)

ThreadPoolExecutor中有方法setCorePoolSize()和setMaximumPoolSize来设置corePoolSize和maximumPoolSize的大小,

  • 如果新值大于旧值,则对新任务新线程
  • 如果新值小于旧值,则在有线程空闲时,减少池中的线程数

但是在实际应用中想实时修改池的线程数,得有一定的条件,特别是要减少线程数,

  • 首先,如果提交的新任务太多,以至总是没有线程空闲下来,线程就不会减少
  • 即使有线程空闲,也不一定能减少线程,这还同所使用的workQueue有关,还需要workQueue.remainingCapacity==0。在JDK所提供的所有BlockingQueue中,只有SynchronousQueue的remainingCapacity()能返回0。

而如果实际应用中需要使用ScheduledThreadPoolExecutor来安排任务,同时需要新安排的任务数又非常多,这时要即时动态线程池的大小,就几乎不可能了,因为ScheduledThreadPoolExecutor用的是LinkedBlockingQueue。这时可以按照JDK的方式实现一个自己的ScheduledThreadPoolExecutor,

首先,稍微修改一下JDK的ThreadPoolExecutor就能实现一个自己的ThreadPoolExecutor,

  • 在setCorePoolSize方法中,去掉workQueue.remainingCapacity==0的条件
  • 让ThreadPoolExecutor中的Worker的interruptIfIdle()方法给Worker设置一个标志,让这个Worker不再检查workQueue中还没有执行的任务,立即中止
  • 还有就是修改一下ThreadPoolExecutor中实现的RejectedExecutionHandler,毕竟很多情况下都可以不需要它

有了自己ThreadPoolExecutor,就可以继承它来实现自己的ScheduledThreadPoolExecutor了(再原本照抄JDK的ScheduledThreadPoolExecutor的实现就可以了^_^)。

根据经验,和专家推荐,corePoolSize的值等于服务器CPU的个数 + 1,就是最优值,可以直接设定死,没必要动态改变。

当然需要计算线程处理时间和等待时间。

根据自己业务的情况,每秒TPS超过一万八,线程启动后不可能闲置,再加上只需要增加线程,一旦线程有任务,不闲置的话减不了,所以就基于ZooKeeper的Worker机制,动态配置,监听回调通知,实时启动新线程来消耗队列任务。

所以用线程池搞不定

 

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值