我对java中的ConcurrentHashMap有疑问。它在内部调用readValueUnderLock。为什么在获取操作时需要锁定。在这种情况下,这种情况将成立 (Entry.value == NULL) 这会导致调用readValueUnderLock)
答案 0 :(得分:4)
来自readValueUnderLock
/**
* Reads value field of an entry under lock. Called if value
* field ever appears to be null. This is possible only if a
* compiler happens to reorder a HashEntry initialization with
* its table assignment, which is legal under memory model
* but is not known to ever occur.
*/
从此link
不完全。你是对的,永远不应该被召唤。 但是,JLS / JMM可以读作并非绝对 禁止因为弱点而被召唤 在决赛中所需的订购关系 vs volatile在构造函数中设置(关键是final,值是 volatile),wrt使用的线程读取 入口物品。 (在JMM-ese中,订购约束 决赛落在同步关系之外。) 这是文档评论(粘贴在下面)引用的问题。 从来没有人想到任何实际的漏洞 处理器/编译器可能会发现生成空值读取, 并且可能证明不存在(也许有一天 JLS / JMM修订版将填补空白以澄清这一点), 但是比尔普格曾经建议我们无论如何都要这样做 为了保守地迂腐正确。 回想起来,我不太确定这是一个好主意,因为 它引导人们提出异国情调的理论。
答案 1 :(得分:0)
为了从哈希映射中读取值,代码必须首先找到该值。如果另一个线程在第一个线程找到值时添加了值,则可能会使搜索脱轨。基本上,哈希映射可以执行以下操作:
calculate hash
go to location hash in the array
look to see if there's a list
iterate through the list until value is found
如果这个列表是一个数组列表而另一个线程需要调整它的大小,那么对于迭代它的线程来说这将是一个很大的问题。