java - 原子计数器更新与阻塞队列的可见性和顺序

标签 java concurrency visibility atomic

如果生产者线程将一个对象添加到多个 BlockingQueue:s 之一,然后递增一个原子整数。消费者线程在轮询每个 BlockingQueue 并找到排队对象之前是否会看到递增的整数值?

文档说,与读取计数器存在发生之前关系。所以我的理解是消费者线程应该始终看到阻塞队列中添加的项目。

我有一个困难的错误,它看起来好像消费者线程首先看到递增的整数,但它们永远无法在它们轮询的阻塞队列中找到任何对象(因为轮询为所有队列返回 null)。所有生产者线程都遵循“添加到队列然后递增计数器”行为。

或者,除了队列为空之外,还有一些未记录的原因可以从轮询 BlockingQueue 中获取 null。

(如果重要的话,我会通过 java.util.concurrent.LinkedBlockingQueue 看到这一点。)

最佳答案

在这种情况下,发生之前关系是添加到队列中发生在写入原子整数之前

为了能够确保这种关系,一个线程需要知道原子整数已更改,或者原子整数的值与队列的当前状态之间存在关联。

根据您的描述很难判断错误是什么,但简单地读取原子整数的值没有任何意义,除非您知道它已更改(或没有更改,具体取决于关系)。

就返回 null 而言。如果调用非等待方法,LinkedBlockingQueue 可以返回 null。例如 poll 是非等待的

Retrieves and removes the head of this queue, or returns null if this queue is empty.

take 将等待队列中存在元素

Retrieves and removes the head of this queue, waiting if necessary until an element becomes available.

关于java - 原子计数器更新与阻塞队列的可见性和顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20545865/

相关文章:

java - Joomla - 使用 javascript 调用用户名

java - 不可序列化对象的分布式缓存

c# - 检测到 ThreadPool WorkItem 已完成/等待完成

grails - 如果超时,是否有任何方法可以获取 PromiseList 的结果

java - 使用private关键字

java - 如何从 JTextField 中获取 Float 值?

java - java.util.Random 真的那么随机吗?我怎样才能生成52! (阶乘)可能的序列?

java - 生产者/消费者 : Consumer needs to remove elements from the shared Queue

c# - 使用 TinyInt 隐藏/显示控件?

java - Perl 共享变量的原子性和可见性