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 实现队列长度指示器


- Safepoint+stats 日志,输出 JDK12 中没有 vmop 操作 2022-01-01
- 从 finally 块返回时 Java 的奇怪行为 2022-01-01
- 如何使用WebFilter实现授权头检查 2022-01-01
- 将log4j 1.2配置转换为log4j 2配置 2022-01-01
- Jersey REST 客户端:发布多部分数据 2022-01-01
- Eclipse 插件更新错误日志在哪里? 2022-01-01
- Spring Boot连接到使用仲裁器运行的MongoDB副本集 2022-01-01
- Java包名称中单词分隔符的约定是什么? 2022-01-01
- value & 是什么意思?0xff 在 Java 中做什么? 2022-01-01
- C++ 和 Java 进程之间的共享内存 2022-01-01