Elegantly implementing queue length indicators to ExecutorServices(优雅地为 ExecutorServices 实现队列长度指示器)
问题描述
为什么,哦,为什么java.util.concurrent
不为其ExecutorService
提供队列长度指标?最近我发现自己在做这样的事情:
Why, oh why doesn't java.util.concurrent
provide a queue length indicators for its ExecutorService
s? Recently I found myself doing something like this:
ExecutorService queue = Executors.newSingleThreadExecutor();
AtomicInteger queueLength = new AtomicInteger();
...
public void addTaskToQueue(Runnable runnable) {
if (queueLength.get() < MAX_QUEUE_LENGTH) {
queueLength.incrementAndGet(); // Increment queue when submitting task.
queue.submit(new Runnable() {
public void run() {
runnable.run();
queueLength.decrementAndGet(); // Decrement queue when task done.
}
});
} else {
// Trigger error: too long queue
}
}
哪个工作正常,但是...我认为这确实应该作为 ExecutorService
的一部分来实现.从实际队列中携带一个 分离 的计数器是愚蠢且容易出错的,计数器应该指示其长度(让我想起了 C 数组).但是,ExecutorService
是通过静态工厂方法获得的,所以没有办法简单地扩展其他优秀的单线程执行器并添加队列计数器.那我该怎么办:
Which works ok, but... I think this really should be implemented as a part of the ExecutorService
. It's dumb and error prone to carry around a counter separated from the actual queue, whose length the counter is supposed to indicate (reminds me of C arrays). But, ExecutorService
s are obtained via static factory methods, so there's no way to simply extend the otherwise excellent single thread executor and add a queue counter. So what should I do:
- 重新发明已经在 JDK 中实现的东西?
- 其他巧妙的解决方案?
推荐答案
还有更直接的方法:
ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newSingleThreadExecutor();
// add jobs
// ...
int size = executor.getQueue().size();
虽然您可能会考虑不使用 Executor 的便捷创建方法,而是直接创建 executor 以摆脱强制转换,从而确保 executor 实际上始终是 ThreadPoolExecutor
,即使 Executors.newSingleThreadExecutor
的实现有一天会改变.
Although you might consider not to use the convenience create methods of Executor, but rather create the executor directly to get rid of the cast and thus be sure that the executor will always actually be a ThreadPoolExecutor
, even if the implementation of Executors.newSingleThreadExecutor
would change some day.
ThreadPoolExecutor executor = new ThreadPoolExecutor( 1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>() );
这是直接从 JDK 1.6 中的 Executors.newSingleThreadExecutor
复制而来的.传递给构造函数的 LinkedBlockingQueue
实际上就是您将从 getQueue
得到的对象.
This is directly copied from Executors.newSingleThreadExecutor
in JDK 1.6. The LinkedBlockingQueue
that is passed to the constructor is actually the very object that you will get back from getQueue
.
这篇关于优雅地为 ExecutorServices 实现队列长度指示器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:优雅地为 ExecutorServices 实现队列长度指示器
基础教程推荐
- Java:带有char数组的println给出乱码 2022-01-01
- 减少 JVM 暂停时间 >1 秒使用 UseConcMarkSweepGC 2022-01-01
- Java Keytool 导入证书后出错,"keytool error: java.io.FileNotFoundException &拒绝访问" 2022-01-01
- “未找到匹配项"使用 matcher 的 group 方法时 2022-01-01
- 设置 bean 时出现 Nullpointerexception 2022-01-01
- 降序排序:Java Map 2022-01-01
- FirebaseListAdapter 不推送聊天应用程序的单个项目 - Firebase-Ui 3.1 2022-01-01
- 在 Libgdx 中处理屏幕的正确方法 2022-01-01
- 如何使用 Java 创建 X509 证书? 2022-01-01
- 无法使用修饰符“public final"访问 java.util.Ha 2022-01-01