我有一个 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),而不是队列。
无论如何,请记住上面的代码不是atomic ,所以不能保证 links.isEmpty()
之间不会发生任何其他事情。和 links.take()
.
编辑:您可以处理 race conditions在带有标志的启动期间:
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
的一部分你绝对应该结账。
关于Java BlockingQueue take() 在 while 循环中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38418267/