当前位置: 首页 > 面试题库 >

具有无限队列的ThreadPoolExecutor不创建新线程

蓝鸿哲
2023-03-14
问题内容

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

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

为什么不创建新线程?


问题答案:

此博客文章介绍了这一难题:

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

如果还需要将最小池大小与最大池大小解耦,则必须进行一些扩展编码。我不知道Java库或Apache
Commons中存在的解决方案解决方案是创建一个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,不用担心这种废话。



 类似资料:
  • 问题内容: 我已经看到了线程池执行程序的实现及其所提供的拒绝执行策略。但是,我有一个自定义要求- 我想拥有一个回调机制,在该机制中,当达到队列大小限制时,我会收到通知,并说何时队列大小减少到最大允许队列大小的80%。 我觉得可以通过子类化线程池执行程序来实现,但是已经有一个实现的版本吗?我很乐意在需要时提供更多详细信息和我的工作,以便提供清晰的信息。 问题答案: 我希望有一个回调机制,当达到队列大

  • 问题内容: 我正在使用的类创建用于运行Web服务器的请求处理程序的固定线程池: 并且说明是: 创建一个线程池,该线程池重用在共享的 无边界 队列上运行的一组固定线程。 但是,我正在寻找实现与缓冲池完全相同的线程池实现,除了使用有 界 队列。有这样的实现吗?还是我需要为固定线程池实现自己的包装器? 问题答案: 您想要做的是新建自己的ExecutorService,可能使用ThreadPoolExec

  • 如果正在运行的线程少于corePoolSize线程,则执行器宁愿添加一个新线程,而不是排队。2)如果corePoolSize或更多线程正在运行,则执行器更喜欢将请求排队,而不是添加新线程。 如果请求无法排队,将创建一个新线程,除非该线程将超过maximumPoolSize,在这种情况下,任务将被拒绝。 第一种情况是可以的,但我想要的是,当核心线程被利用时,任务不需要排队(即使在有界队列的情况下,比

  • 以下是Sun创建线程的简单规则: 如果线程数小于corePoolSize,请创建新线程以运行新任务 为什么在队列已满时创建非核心线程?我不明白他们为什么这样做。为什么不在队列为空时创建非核心线程?

  • 我收到了一个关于这个问题的建议,一个评论,说我可能没有我需要的交换,因为我的队列已经存在。于是,我就全部手动删除了。 但是,在重新部署应用程序时,我发现所有队列都有以下异常: 我不确定这意味着什么,因为我显然想要创建队列<code>myInput。组,它似乎在抱怨它不存在。。。 我也检查了这个问题,我的问题可能是权限。但我应该有它们——否则我相信我无法删除队列...... 你能给我一个解决方案吗?

  • 我正在尝试创建一个具有一定数量线程的ThreadPoolExector,但同时,我想控制池队列的大小。所以我使用完整的构造函数创建了执行器: 然而,这给了我一个非法辩论例外。如果我将构造函数更改为 它起作用了。如果我希望理想的线程数和最大线程数相同,为什么它不起作用呢。