[英]Java BlockingQueue take() in a while loop
我有一个BlockingQueue,它由一个带有put()的线程填充。 但我对如何为BlockingQueue执行take()感到困惑。 目前我以这种方式实现它:
String link;
try {
while(!(link = links.take()).isEmpty()) {
System.out.println(link);
}
} catch(InterruptedException ex) {
ex.printStackTrace();
}
是对的吗? 如果不在条件语句中,如何循环队列并分配字符串变量?
如果我理解正确的,你问的方式来take
的条件之外? 嗯,这并不难:
while (!links.isEmpty()) {
try {
String link = links.take();
// Do stuff.
} catch (InterruptedException e) {
// Exception handling.
}
}
您当前的状况!(link = links.take()).isEmpty()
检查返回值 - 字符串 - 是否为空(长度等于0),而不是队列。
无论如何,请记住上面的代码不是原子的 ,所以不能保证在links.isEmpty()
和links.take()
之间不会发生任何其他事情。
编辑:您可以在启动期间使用标志处理竞争条件 :
BlockingQueue<Integer> numbers = new ArrayBlockingQueue<>(10);
AtomicBoolean flag = new AtomicBoolean(true);
// Producer.
new Thread(() -> {
for (int i = 0; i < 10; i++) {
try {
numbers.put(i);
} catch (InterruptedException e) { /* NOP */ }
}
flag.set(false);
}).start();
// Consumer.
while (flag.get() || !numbers.isEmpty()) {
try {
System.out.println(numbers.take());
} catch (InterruptedException e) { /* NOP */ }
}
这里AtomicBoolean
,但如果您有多个生产者和/或消费者,它可能会变得很方便。 它也是你应该结帐的java.util.concurrent
的一部分。
我的理解是你问的是如何以一种好的方式终止BlockingQueue。 我能想到两种情况。 在任何情况下,您都有一个消息生成器A和消息使用者B.
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.