【发布时间】:2013-03-04 00:32:19
【问题描述】:
我发现自己在重复这种模式,并且经常想知道它是否在 Java 中是惯用的,或者有更好的方法来实现这种行为。
问题:给定生产者/消费者设置,消费者想要处理批量项目,因此它使用drainTo(),但是drainTo() 将轮询现有项目并且可能无法获取任何项目,以避免这个 I 前缀使用take() 确保它在至少有一件物品可用之前阻塞。
对于特定数据集,我遇到的一个问题是,在许多用例中,批量大小通常在 (1, N, 1, N) 之间交替出现不规则。一般来说,这是解决此问题的常用方法:
例子:
ArrayBlockingQueue<Foo> queue;
function void produce() {
while(true) {
queue.put(createFoo());
}
}
function void consumeBatchSpin() {
while(true) {
List<Foo> batch = Lists.newLinkedList();
queue.drainTo(batch);
doSomething(batch);
//the problem here is that if nothing is being produced, this loop will spin
}
}
function void consumeBatchTake() {
while(true) {
List<Foo> batch = Lists.newLinkedList();
batch.add(queue.take()); //force at least one item to be there
queue.drainTo(batch);
doSomething(batch);
}
}
【问题讨论】:
-
stackoverflow.com/a/831861/139010 和 cs.oswego.edu/pipermail/concurrency-interest/2006-July/… 所以是的,这似乎是一个不完全不常见的解决方案。
标签: java concurrency