4

我对 Java 中的 ConcurrentHashMap 有疑问。它在内部调用 readValueUnderLock。为什么在获取操作的情况下需要锁定。在这种情况下,此条件将为真(Entry.value==null),这会导致调用 readValueUnderLock)

4

2 回答 2

4

来自源代码 java doc 的注释 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.
     */

从这个链接

不完全的。你是对的,它永远不应该被调用。但是,JLS/JMM 可以被解读为并非绝对禁止调用它,因为在构造函数中设置的 final 与 volatile 之间所需的顺序关系存在弱点(键是 final,值是 volatile),线程使用条目对象进行读取. (在 JMM-ese 中,final 的排序约束不属于 synchronizes-with 关系。)这就是文档注释(粘贴在下面)所指的问题。没有人想过处理器/编译器可能会发现任何实际漏洞来产生空值读取,并且可能证明不存在任何漏洞(也许有一天 JLS/JMM 修订版会填补空白以澄清这一点),但是Bill Pugh 曾经建议我们把它放在任何地方,只是为了保守地迂腐正确。

于 2012-10-05T07:07:39.767 回答
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

如果这个列表是一个数组列表并且另一个线程需要调整它的大小,这对于遍历它的线程来说将是一个大问题。

于 2012-10-05T06:41:54.053 回答