gpt4 book ai didi

java - ThreadPoolExecutor 在队列满时阻塞?

转载 作者:IT老高 更新时间:2023-10-28 20:29:12 28 4
gpt4 key购买 nike

我正在尝试使用 ThreadPoolExecutor 执行大量任务。下面是一个假设的例子:

def workQueue = new ArrayBlockingQueue<Runnable>(3, false)
def threadPoolExecutor = new ThreadPoolExecutor(3, 3, 1L, TimeUnit.HOURS, workQueue)
for(int i = 0; i < 100000; i++)
threadPoolExecutor.execute(runnable)

问题是我很快得到一个 java.util.concurrent.RejectedExecutionException 因为任务的数量超过了工作队列的大小。但是,我正在寻找的期望行为是让主线程阻塞,直到队列中有空间。实现这一目标的最佳方法是什么?

最佳答案

在一些非常狭窄的情况下,您可以实现一个 java.util.concurrent.RejectedExecutionHandler 来满足您的需要。

RejectedExecutionHandler block = new RejectedExecutionHandler() {
rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
executor.getQueue().put( r );
}
};

ThreadPoolExecutor pool = new ...
pool.setRejectedExecutionHandler(block);

现在。这是一个非常糟糕的主意,原因如下

  • 它很容易出现死锁,因为池中的所有线程都可能在您放入队列中的东西可见之前就死了。通过设置合理的保持 Activity 时间来缓解此问题。
  • 任务未按照您的 Executor 预期的方式包装。许多执行器实现在执行之前将它们的任务包装在某种跟踪对象中。看看你的来源。
  • API 强烈反对通过 getQueue() 添加,并且在某些时候可能会被禁止。

几乎总是更好的策略是安装 ThreadPoolExecutor.CallerRunsPolicy,它将通过在调用 execute() 的线程上运行任务来限制您的应用程序。

但是,有时阻止策略及其所有固有风险确实是您想要的。我会说在这些条件下

  • 你只有一个线程调用 execute()
  • 您必须(或希望)有一个非常小的队列长度
  • 您绝对需要限制运行此工作的线程数(通常是出于外部原因),而调用者运行策略会破坏这一点。
  • 您的任务大小无法预测,因此如果池暂时忙于 4 个短任务并且您的一个线程调用 execute 被一个大任务卡住,调用者运行可能会导致饥饿。

所以,正如我所说。它很少需要,而且可能很危险,但你去吧。

祝你好运。

关于java - ThreadPoolExecutor 在队列满时阻塞?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3446011/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com