我对Java中的ConcurrentHashMap有一个问题。它在内部调用readValueUnderLock。为什么在进行get操作时需要锁定。在哪种情况下会出现下列条件为真的情况(Entry.value==null),导致调用readValueUnderLock。
我对Java中的ConcurrentHashMap有一个问题。它在内部调用readValueUnderLock。为什么在进行get操作时需要锁定。在哪种情况下会出现下列条件为真的情况(Entry.value==null),导致调用readValueUnderLock。
readValueUnderLock
方法的Java源代码文档注释:
/**
* 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可以被理解为并未绝对禁止其被调用, 因为构造函数中所需的finals和volatiles之间的顺序关系存在弱点 (key是final,value是volatile),对于使用entry对象读取的线程来说, 这就涉及到了问题。(在JMM-ese中,finals的排序限制超出了同步关系。) 这就是文档注释(如下所示)所指的问题。 没有人想到过任何实际漏洞,即处理器/编译器可能找到的产生空值读取的漏洞, 可能可以证明不存在这样的漏洞(也许有一天JLS/JMM的修订将填补这些空白以澄清这一点), 但Bill Pugh曾建议我们把这个放进去,只是为了保守地严谨正确。 回想起来,我不太确定这是一个好主意,因为它会导致人们提出奇特的理论。
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