先来一个动态更新的代码示例:
- 上面的程序就是自定义了一个核心线程数为 2,最大线程数为 5,队列长度为 10 的线程池。
- 然后给它塞 15 个耗时 10 秒的任务,直接让它 5 个最大线程都在工作,队列长度 10 个都塞满。
- 当前的情况下,队列里面的 10 个,前 5 个在 10 秒后会被执行,后 5 个在 20 秒后会被执行。
- 再加上最大线程数正在执行的 5 个,15 个任务全部执行完全需要 3 个 10 秒即 30 秒的时间。
- 这个时候,如果我们把核心线程数和最大线程数都修改为 10。
- 那么 10 个任务会直接被 10 个最大线程数接管,10 秒就会被处理完成。
- 剩下的 5 个任务在队列里面,在 10 秒后被执行完成。
- 所以,15 个任务执行完成需要 2 个 10 秒即 20 秒的时间处理完成了。
看一下上面程序的打印日志:
效果实现了,我先看一下原理是什么。
先看 setCorePoolSize 方法:
- 在运行期线程池使用方调用此方法设置corePoolSize之后,线程池会直接覆盖原来的corePoolSize值,并且基于当前值和原始值的比较结果采取不同的处理策略。
- 对于当前值小于当前工作线程数的情况,说明有多余的worker线程,此时会向当前idle的worker线程发起中断请求以实现回收,多余的worker在下次idel的时候也会被回收;
- 对于当前值大于原始值且当前队列中有待执行任务,则线程池会创建新的worker线程来执行队列任务,setCorePoolSize具体流程如下:
接着看 setMaximumPoolSize 源码:
这个地方就很简单了,逻辑不太复杂。
-
首先是参数合法性校验。
-
然后用传递进来的值,覆盖原来的值。
-
判断工作线程是否是大于最大线程数,如果大于,则对空闲线程发起中断请求。
经过前面两个方法的分析,我们知道了最大线程数和核心线程数可以动态调整。