Java 中 ThreadPoolExecutor 的 corePoolSize 配置陷阱,以及max配置值何时生效的问题

问题

    ThreadPoolExecutor queryExecutor = new ThreadPoolExecutor(1, 10, 60, TimeUnit.MINUTES, new ArrayBlockingQueue<>(10000));

我创建了一个线程池执行器,但是我发现它只会串行执行任务(相关任务数量少,但执行时间较长),并不是和预期一样的并行执行任务。这是因为我的 corePoolSize错误地配置为1

原因

创建的线程池方法签名如下

Creates a new ThreadPoolExecutor with the given initial parameters and default thread factory and rejected execution handler. It may be more convenient to use one of the Executors factory methods instead of this general purpose constructor.
Params:
corePoolSize – the number of threads to keep in the pool, even if they are idle, unless allowCoreThreadTimeOut is set
maximumPoolSize – the maximum number of threads to allow in the pool
keepAliveTime – when the number of threads is greater than the core, this is the maximum time that excess idle threads will wait for new tasks before terminating.
unit– the time unit for the keepAliveTime argument
workQueue– the queue to use for holding tasks before they are executed. This queue will hold only the Runnable tasks submitted by the execute method.

错误地认为 corePoolSize 是最小线程数的概念。

*When a new task is submitted in method {**@link** #execute(Runnable)}, and fewer than corePoolSize threads are running, a new thread is* created to handle the request, even if other worker threads are idle. If there are more than corePoolSize but less than maximumPoolSize threads running, a new thread will be created only if the queue is full. By setting corePoolSize and maximumPoolSize the same, you create a fixed-size thread pool. By setting maximumPoolSize to an essentially unbounded value such as {**@code*** Integer.MAX_VALUE}, you allow the pool to accommodate an arbitrary number of concurrent tasks. Most typically, core and maximum pool* sizes are set only upon construction, but they may also be changed dynamically using {**@link** #setCorePoolSize} and {**@link*** #setMaximumPoolSize}. </dd>**

文档上写得很清楚*If there are more than corePoolSize but less than maximumPoolSize threads running, a new thread will be created only if the queue is full* 。仅有在等待队列满后,且运行线程数小于最大线程数时才会创建新线程来执行任务。

我的 corePoolSize 为1,而队列长度却为10000(在我的场景里这等于无限长),这意味着永远不会有超出1的线程数来帮我并行执行任务。

总结

使用功能前还是要多看文档,此外也要多测试功能是否符合预期效果。这种场景出 bug 也难写个单测来覆盖,只能手动测试。

posted @   casa_fox  阅读(16)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)
点击右上角即可分享
微信分享提示