我在java中有一个关于ConcurrentHashMap的问题.它在内部调用readValueUnderLock.为什么在获取操作时需要锁定.在这种情况下,这种情况将成立
(Entry.value == NULL)
导致调用readValueUnderLock)
解决方法:
从源代码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.
*/
从这link
Not quite. You are right that it should never be called.
However, the JLS/JMM can be read as not absolutely
forbidding it from being called because of weaknesses
in required ordering relationships among finals
vs volatiles set in constructors (key is final, value is
volatile), wrt the reads by threads using the
entry objects. (In JMM-ese, ordering constraints for
finals fall outside of the synchronizes-with relation.)
That’s the issue the doc comment (pasted below) refers to.
No one has ever thought of any practical loophole that a
processor/compiler might find to produce a null value read,
and it may be provable that none exist (and perhaps someday
a JLS/JMM revision will fill in gaps to clarify this),
but Bill Pugh once suggested we put this in anyway just
for the sake of being conservatively pedantically correct.
In retrospect, I’m not so sure this was a good idea, since
it leads people to come up with exotic theories.