gpt4 book ai didi

java - ArrayBlockingQueue 中类型为 Runnable 的毒丸

转载 作者:行者123 更新时间:2023-12-02 01:54:13 27 4
gpt4 key购买 nike

我有一个阻塞队列,其中包含要执行的任务:

private final BlockingQueue<Runnable> queue = new ArrayBlockingQueue<>(20);
private final AtomicInteger isPoisingPill = new AtomicInteger(2); //two producers

还有一个消费者:

while (isPoisingPill.get() != 0) {
processExecutor.submit(this.kpiData.take()));
}

每个提供者在完成一项工作时,执行:isPoisingPill.decrementAndGet();

但它并非在所有情况下都有效。有时当我们进入循环时,生产者将 PoisingPill 置为 false,然后程序挂起,因为操作 take() 正在等待队列中的元素,而它却没有,因为制作人已经完成了。事实证明,药丸应该直接放入队列中,并且在循环中已经检查了相等性。但是,如果队列仅包含 Runnable 对象,我应该在那里放什么?

还有一种情况是我有很多制作人。我们需要等待它们完成。

最佳答案

是的,毒丸应该添加到任务队列中。您可以创建自己的类,扩展Runnable并具有 boolean 标志

public class MyRunnable implements Runnable {
private boolean posionPill = false;

public Boolean isPosionPill() {
return poisonPill;
}
..... // your other stuff
}

当您调用 take() 时,请在开始执行 Runnable 之前检查该标志

另一种选择是

public static final Runnable POISON_PILL = new Runnable() { 
public void run(){}
};

在代码中的某个位置,将该静态对象添加到队列中,并在 take() 之后将队列中的对象与该常量进行比较

在消费者中你需要做这样的事情

int pillsCount = 0;
while (pillsCount < 2) {
MyRunnable task = queue.take();
if (task.isPoisonPill()) {
++pillsCount;
} else {
executor.submit(task);
}
}

关于java - ArrayBlockingQueue 中类型为 Runnable 的毒丸,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52543547/

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