具有无限队列的ThreadPoolExecutor不创建新线程 [英] ThreadPoolExecutor with unbounded queue not creating new threads

查看:323
本文介绍了具有无限队列的ThreadPoolExecutor不创建新线程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的ThreadPoolExecutor无法创建新线程.实际上,我写了一个有点怪异的LinkedBlockingQueue,它将接受任何任务(即,它是不受限制的),但调用了一个附加处理程序-在我的应用程序中,它会发出警告跟踪表明该池已在后面-这为我提供了非常明确的信息,即TPE是即使队列中有成千上万的条目,也拒绝创建新线程.我的构造函数如下:

My ThreadPoolExecutor is failing to create new threads. In fact I wrote a somewhat hacky LinkedBlockingQueue that will accept any task (i.e. it is unbounded) but call an additional handler - which in my application spews warning trace that the pool is behind - which gives me very explicit information that the TPE is refusing to create new threads even though the queue has thousands of entries in it. My constructor is as follows:

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

为什么不创建新线程?

推荐答案

这种线程池构造根本无法按预期工作.这是由于ThreadPoolExecutor中的逻辑所致,如果存在失败来向队列提供任务,则会添加新线程.在本例中,我们使用无限制的LinkedBlockingQueue,在此我们始终可以向队列提供任务.这实际上意味着我们永远不会超过核心池大小,而不会增长到最大池大小.

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没有可用线程,它将竭尽全力拒绝任务,然后手动重新排队.在链接的文章中有更详细的介绍.最终,您的构造将如下所示:

If you also need to decouple the minimum from maximum pool sizes, you will have to do some extended coding. I am not aware of a solution that exists in the Java libraries or Apache Commons. The solution is to create a coupled BlockingQueue that is aware of the TPE, and will go out of its way to reject a task if it knows the TPE has no threads available, then manually requeue. It is covered in more detail in linked post. Ultimately your construction will look like:

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,不要担心这种废话.

However more simply set corePoolSize to maxPoolSize and don't worry about this nonsense.

这篇关于具有无限队列的ThreadPoolExecutor不创建新线程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆