在线程池的使用过程中,他的核心参数配置一直是一个很让人头疼的问题。
在《美团Java线程池原理及其在美团业务中的实践》中,我找到了这张图。

经过美团技术人员的调研,发现并不能得出一个通用的线程池计算方式。并发任务的执行情况和任务类型相关,IO密集型和CPU密集型的任务运行起来的情况差异非常大,但这种占比是较难合理预估的,这导致很难有一个简单有效的通用公式帮我们直接计算出结果。
尽管经过谨慎的评估,仍然不能够保证一次计算出来合适的参数,那么我们是否可以将修改线程池参数的成本降下来,这样至少可以发生故障的时候可以快速调整从而缩短故障恢复的时间呢?
于是乎,我基于《美团Java线程池原理及其在美团业务中的实践》里的思路实现了一个简易的线程池动态配置的实现demo。
这是我的代码gitee的地址:dynamic-thread-pool-demo
1.找到线程池中设置 核心参数 corePoolSize(核心线程数)、maximumPoolSize(最大线程数)、queueCapacity(阻塞队列长度)的方法。经过源码阅读,发现


但是又发现阻塞队列的capacity属性是final修饰的,也就是不可修改的。咱们该如何修改capacity的大小呢?
2.重写一个新的LinkedBlockingQueue命名为MyLinkedBlockingQueue,将LinkedBlockingQueue代码迁移过来,然后将capacity的final修饰去除,同时实现它的set,get方法。

3.新建一个DynamicThreadPoolDemo类,新建一个创建自定义线程池的方法,阻塞线程池用MyLinkedBlockingQueue

4.为了验证动态调整参数是否有效,咱们先建一个枚举,用来表示线程池的状态

5.创建 printExecutorInfo方法,打印一下当前线程池的信息数据

6.创建main方法来验证动态调参。

7.如何验证?如果不改变参数的情况下,15个任务,最大线程数为5,那么运行时间大概是30s左右。改变参数之后,最大线程数为10个,那么15个任务只需要20s就可以全部完成
8.运行程序,查看控制台,验证结果

9.经过程序的验证发现动态调参是可行的。在咱们实际生产环境中该如何落地呢?可以考虑在配置中心(例如Apollo)上进行调参