高峰期把 corePoolSize 从 16 调到 64,接口耗时没变化,队列长度还是 5000,jstack 里线程数仍然是 16。碰到这种情况,我一般先确认改动有没有真的生效。

原因不复杂,线程池只有在入队失败或者线程数小于核心数时才会新建线程,队列没满的情况下任务都进了队列,扩容条件根本不触发。核心线程数调大也不会立刻创建线程,只影响后续判断。

「动态调整线程数」这类改动最怕改一半,回滚脚本先准备好,再动生产。日志级别临时调高可以,记得改回去,长期开着既占磁盘又掩盖真问题。

pool.setCorePoolSize(64);
pool.setMaximumPoolSize(128);
System.out.println(pool.getPoolSize() + " / " + pool.getQueue().size());

权限不要一口气开到最大,先加到够用再往上试,范围小才好收。把复现步骤压到三条以内,交给同事也能跑出来,才算真的定位清楚。

具体做法是,先确认队列是否有界 无界队列永远不会触发扩容;动态调整时同时看 getPoolSize 和队列长度;必要时调 setMaximumPoolSize 再配合有界队列;用 setCorePoolSize 后主动提交探针任务验证线程数变化。

最后用这个标准收尾,调整后 10 秒内线程数涨到 60 以上,队列长度开始下降。

作者 9823189