gpt4 book ai didi

java - 在排空 ArrayBlockingQueue 之前阻塞

转载 作者:行者123 更新时间:2023-12-01 14:48:05 24 4
gpt4 key购买 nike

我发现自己在重复这种模式,并且常常想知道这在 Java 中是否是惯用的,或者是否有更好的方法来实现这种行为。

问题:给定生产者/消费者设置,消费者想要处理批量的项目,因此它使用 drainTo(),但是 drainTo() 将轮询现有的项目,并且可能无法获取任何项目,为了避免这种情况,我在排水管前添加了 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);
}
}

最佳答案

您是否考虑过添加到列表并在获取时获取整个列表。

我发布了一个here最近。正在接受代码审查 here但我的测试表明它很强大。

本质上,当您执行 put 操作时,您会将新元素添加到当前列表中。当您执行 get 操作时,您将获得整个列表,并以原子方式将其替换为新的空列表。

无需使用drainTo并且根本不需要旋转。

关于java - 在排空 ArrayBlockingQueue 之前阻塞,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15192736/

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