java - 具有无界队列的 ThreadPoolExecutor 不创建新线程

标签 java multithreading threadpool threadpoolexecutor

我的 ThreadPoolExecutor 无法创建新线程。事实上,我写了一个有点老套的 LinkedBlockingQueue ,它将接受任何任务(即它是无界的)但调用一个额外的处理程序 - 在我的应用程序中发出警告跟踪池在后面 - 这给了我非常明确的TPE 拒绝创建新线程的信息,即使队列中有数千个条目也是如此。我的构造函数如下:

private final ExecutorService s3UploadPool = 
new ThreadPoolExecutor(1, 40, 1, TimeUnit.HOURS, unboundedLoggingQueue);

为什么不创建新线程?

最佳答案

这个陷阱包含在 this blog post 中:

This construction of thread pool will simply not work as expected. This is due to the logic within the ThreadPoolExecutor where new threads are added if there is a failure to offer a task to the queue. In our case, we use an unbounded LinkedBlockingQueue, where we can always offer a task to the queue. It effectively means that we will never grow above the core pool size and up to the maximum pool size.

如果您还需要将最小池大小与最大池大小分离,则必须进行一些扩展编码。我不知道 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,不用担心这些废话。

关于java - 具有无界队列的 ThreadPoolExecutor 不创建新线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15485840/

相关文章:

java - 当每个人都对 OSGi 进行标准化时,为什么 Sun 还要发明另一个模块系统?

java - 将 JUnitCore ( JUnit ) 更改为 TestNG

java - 使 Ant 脚本中的 Java 步骤导致构建失败

java - 使用递归用星形创建三角形

c# - 多线程sqldatareader时间过期

java - 有效实现此 Java MouseListener 逻辑

java - 如何实现执行结束自动关闭的线程池?

java - SwingWorker 的 ExecutorService 参数

multithreading - C++11线程池——带输入参数的任务

c# - 嵌套并行 For 中的死锁风险