如何动态调整线程池参数
为了方便动态调整线程池参数,将线程池参数的配置放到配置中心中,比如 Nacos,Apollo。
在七个线程池参数中,corePoolSize(核心线程数),maximumPoolSize(最大线程数),workQueue(阻塞队列),handler(拒绝策略),一般需要动态调整这四个参数,最重要的参数是 corePoolSize。
具体该如何调整线程池参数,跟使用的场景有关,首先会想到操作是 cpu 密集型还是 IO 密集型,但是一般在项目中使用线程池时, cpu 和 io 一般很难分隔开,所以我们需要动态调整 corePoolSize。
使用 top
, vmstat
或 mpstat
查看服务器的 cpu 利用率
关键指标:
%us
:用户态CPU 利用率(消耗总CPU 的时间比例)%sy
:内核态CPU 利用率%id
:空闲CPU 比例%wa
:CPU 等待 I/O 的时间cs
:上下文切换次数
通过 top
分析CPU 利用率
按 Shift + P
按 CPU 排序,如果 Java 进程 %CPU 接近 100%,则 CPU 负载,如果长期低于 50%,可能存在资源浪费。
CPU 利用率高时的处理策略
现象:%us
用户态CPU 利用率高,线程池的队列堆积,使用 vmstat
发现 cs
上下文切换次数较多
可能原因:
- 线程数创建过多,频繁上下文切换
- 队列容量过小
调整方案:
- 减少 corePoolSize
- 增大队列容量
- 优化任务处理逻辑,减少锁竞争或使用异步处理降低 CPU 压力
CPU 利用率低时的处理策略
现象:%id
高,空闲CPU 多
可能原因:
- 线程数不足:无法充分利用 CPU。
- 任务存在外部阻塞:如数据库响应慢、远程调用阻塞。
- 队列容量过大:任务堆积在队列,未及时调度到线程。
调整方案:
- 增加 corePoolSize
- 减少队列容量