【发布时间】:2011-07-31 22:50:36
【问题描述】:
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;博士
给定一个ThreadPoolExecutor,配置如下:
- 核心线程 > 0
- 核心线程不允许超时
- 核心线程已预先启动
- 保留对支持执行程序的
BlockingQueue的引用
是否可以直接将任务添加到队列而不是调用executor.execute()?
相关
这个问题 (producer/consumer work queues) 类似,但不具体涉及直接添加到队列中。
【问题讨论】:
-
“我保留了对队列的引用,因此我可以直接向其中添加任务”但是您为什么要这样做?为什么不直接将它们提交给执行者?
-
@Raedwald,见上面我写的地方“我上面例子中的方法有利于阻塞队列......”
标签: java concurrency producer-consumer executorservice blockingqueue