与ThreadPoolExecutor的无界队列没有创造新主题(ThreadPoolExecutor

2019-08-17 17:33发布

ThreadPoolExecutor未能创建新线程。 事实上,我写了一个有点哈克LinkedBlockingQueue ,将接受任何任务(即它是无限的),但调用额外的处理程序-这在我的应用程序喷出警告痕迹,游泳池后面-这给了我非常明确的信息是,TPE被拒绝创建新的线程,即使队列中有成千上万个条目,在它。 我的构造函数如下:

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

为什么没有创造新主题?

Answer 1:

这种疑难杂症是覆盖在这篇博客文章 :

如预期线程池的这种结构根本不起作用。 这是因为在那里新的线程将添加,如果有一个未能提供到队列中的任务的ThreadPoolExecutor中的逻辑。 在我们的例子中,我们使用无界的LinkedBlockingQueue,在这里我们可以随时提供给队列的任务。 这实际上意味着,我们永远不会长出核心池大小,并达到最大池大小。

如果您还需要从脱钩最大池大小最小,你将不得不做一些扩展编码。 我不知道存在于Java库或Apache共享的解决方案的。 该解决方案是创建一个耦合BlockingQueue是知道TPE,并会走出它的方式拒绝一个任务,如果它知道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;
}

然而,更简单的设置corePoolSizemaxPoolSize ,不要担心这个无稽之谈。



Answer 2:

正如@djechlin提到的,这是(到许多令人惊奇的)中限定的的行为的部分ThreadPoolExecutor 。 我相信我已经找到了解决此问题,我表现出在这里我的回答有点优雅的解决方案:

如何获得的ThreadPoolExecutor增加线程最大排队过吗?

基本上你扩展LinkedBlockingQueue有它总是返回假queue.offer(...)这将额外的线程,如果有必要添加到池中。 如果池已经是最大线程数和他们都忙, RejectedExecutionHandler将被调用。 这是处理程序,然后做了put(...)到队列中。

见我的代码存在。



Answer 3:

有一个解决此问题的。 请看下面的实现:

int corePoolSize = 40;
int maximumPoolSize = 40;
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, 
    60L, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>());
threadPoolExecutor.allowCoreThreadTimeOut(true);

通过设置allowCoreThreadTimeOut()到true ,在池中的线程被允许在指定的超时(60秒在该实施例中)之后终止。 有了这个解决方案,它是corePoolSize构造函数的参数,确定在实践中,最大池大小,因为线程池将增长到corePoolSize ,然后开始添加作业队列中。 这是可能的池可能永远不会比大,因为池不会产生新的线程,直到队列已满(其中,考虑到LinkedBlockingQueueInteger.MAX_VALUE容量可能永远不会发生)。 因此,人们在制定小点maximumPoolSize比一个较大的值corePoolSize

代价:线程池有0空闲线程后超时已经到期,这意味着会有一些延迟在创建线程之前(通常情况下,你总是有corePoolSize可用线程)。

更多的细节可以在JavaDoc中可以找到的ThreadPoolExecutor 。



文章来源: ThreadPoolExecutor with unbounded queue not creating new threads