ArrayBlockingQueue 中 Runnable 类型的毒丸

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


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对象,我应该在那里放什么?


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


HUWWW
浏览 183回答 1
1回答

蓝山帝景

是的,毒丸应该与任务一起添加到队列中。您可以创建自己的类扩展Runnable并具有布尔标志public class MyRunnable implements Runnable {&nbsp; private boolean posionPill = false;&nbsp; public Boolean isPosionPill() {&nbsp; &nbsp; return poisonPill;&nbsp; }&nbsp; ..... // your other stuff}当您take()在开始执行之前调用检查该标志时Runnable另一种选择是有public static final Runnable POISON_PILL = new Runnable() {&nbsp;&nbsp; public void run(){}};在您的代码中的某处并将该静态对象添加到队列中,然后take()将队列中的对象与该常量进行比较而在消费者中,你需要做这样的事情int pillsCount = 0;while (pillsCount < 2) {&nbsp; MyRunnable task = queue.take();&nbsp; if (task.isPoisonPill()) {&nbsp; &nbsp; ++pillsCount;&nbsp; } else {&nbsp; &nbsp; executor.submit(task);&nbsp; }}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java