gpt4 book ai didi

java - 向 ThreadPoolExecutor 的 BlockingQueue 添加任务是否可取?

转载 作者:太空狗 更新时间:2023-10-29 22:33:45 28 4
gpt4 key购买 nike

ThreadPoolExecutor 的 JavaDoc尚不清楚将任务直接添加到支持执行程序的 BlockingQueue 是否可以接受。 The docs say调用 executor.getQueue() 是“主要用于调试和监控”。

我正在用我自己的 BlockingQueue 构建一个 ThreadPoolExecutor。我保留了对队列的引用,因此我可以直接向其中添加任务。 getQueue() 返回相同的队列,因此我假设 getQueue() 中的警告适用于对通过我的方式获取的后备队列的引用。

例子

代码的一般模式是:

int n = ...; // number of threads
queue = new ArrayBlockingQueue<Runnable>(queueSize);
executor = new ThreadPoolExecutor(n, n, 1, TimeUnit.HOURS, queue);
executor.prestartAllCoreThreads();
// ...
while (...) {
Runnable job = ...;
queue.offer(job, 1, TimeUnit.HOURS);
}
while (jobsOutstanding.get() != 0) {
try {
Thread.sleep(...);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
executor.shutdownNow();

queue.offer()executor.execute()

据我了解,典型的用途是通过executor.execute() 添加任务。我上面示例中的方法具有阻塞队列的好处,而如果队列已满并拒绝我的任务,execute() 会立即失败。我也喜欢提交作业与阻塞队列交互;这对我来说感觉更“纯粹”的生产者-消费者。

直接将任务添加到队列的含义:我必须调用 prestartAllCoreThreads() 否则没有工作线程正在运行。假设没有与执行器的其他交互,则不会有任何东西监视队列(对 ThreadPoolExecutor 源代码的检查证实了这一点)。这也意味着对于直接排队,ThreadPoolExecutor 必须另外配置为 > 0 个核心线程,并且不得配置为允许核心线程超时。

tl;dr

给定一个 ThreadPoolExecutor 配置如下:

  • 核心线程> 0
  • 核心线程不允许超时
  • 核心线程已预启动
  • 持有对支持执行器的 BlockingQueue 的引用

是否可以直接将任务添加到队列而不是调用 executor.execute()

相关

这个问题 ( producer/consumer work queues ) 类似,但没有具体涉及直接添加到队列。

最佳答案

一个技巧是实现 ArrayBlockingQueue 的自定义子类并覆盖 offer() 方法来调用您的阻塞版本,然后您仍然可以使用正常的代码路径。

queue = new ArrayBlockingQueue<Runnable>(queueSize) {
@Override public boolean offer(Runnable runnable) {
try {
return offer(runnable, 1, TimeUnit.HOURS);
} catch(InterruptedException e) {
// return interrupt status to caller
Thread.currentThread().interrupt();
}
return false;
}
};

(正如您可能猜到的那样,我认为直接在队列上调用 offer 作为您的正常代码路径可能不是一个好主意)。

关于java - 向 ThreadPoolExecutor 的 BlockingQueue 添加任务是否可取?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5585927/

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