这篇博文介绍了这个问题:
这种线程池的构造根本无法按预期工作。这是由于 ThreadPoolExecutor 中的逻辑,如果无法向队列提供任务,则会添加新线程。在我们的例子中,我们使用了一个无界的 LinkedBlockingQueue,我们总是可以向队列提供一个任务。这实际上意味着我们永远不会超过核心池大小并达到最大池大小。
如果您还需要将最小池大小与最大池大小分离,则必须进行一些扩展编码。我不知道 Java 库或 Apache Commons 中存在的解决方案。解决方案是创建一个知道 TPE 的耦合BlockingQueue
器,如果它知道 TPE 没有可用的线程,它会竭尽全力拒绝任务,然后手动重新排队。它在链接的帖子中有更详细的介绍。最终,您的构造将如下所示:
public static ExecutorService newScalingThreadPool(int min, int max, long keepAliveTime) {
ScalingQueue queue = new ScalingQueue();
ThreadPoolExecutor executor =
new ScalingThreadPoolExecutor(min, max, keepAliveTime, TimeUnit.MILLISECONDS, queue);
executor.setRejectedExecutionHandler(new ForceQueuePolicy());
queue.setThreadPoolExecutor(executor);
return executor;
}
然而,更简单地设置并不corePoolSize
要maxPoolSize
担心这种废话。