Java BlockingQueue take() 在 while 循环中

标签 java asynchronous blockingqueue

我有一个 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/

相关文章:

java - 将输入的长度限制为 x 位数

python - 池.apply_async() : nested function is not executed

c++ - 创建阻塞队列

javascript - 在 ajax 回调函数的每个循环之后附加输出

java - 任何允许组合条目的高效 BlockingQueue 实现?

Java BlockingQueue 似乎在传输过程中损坏了数据

java - 方法内部类约定

java - 在 Java 类中实现 Getter 和 Setter 方法是否总是合适的

java - 获取 arrayList 中的特定对象

c# - 为什么要在 C# 中使用 Task<T> 而不是 ValueTask<T>?