ConcurrentHashMap的get方法中为什么存在readValueUnderLock(e)?
Why readValueUnderLock(e) exist in ConcurrentHashMap’s get method?
在JDK1.6
阅读ConcurrentHashMap
的源码时,发现readValueUnderLock(e)
无法访问,因为put方法已经检查了值:if value is null,它必须抛出 NullPointerException
。所以我认为可能有问题,但我不确定它是什么。如果有人能回答我,我将不胜感激!
一些源代码在这里:
V get(Object key, int hash) {
if (count != 0) { // read-volatile
HashEntry<K,V> e = getFirst(hash);
while (e != null) {
if (e.hash == hash && key.equals(e.key)) {
V v = e.value;
if (v != null)
return v;
return readValueUnderLock(e); // recheck
}
e = e.next;
}
}
return null;
}
V readValueUnderLock(HashEntry<K,V> e) {
lock();
try {
return e.value;
} finally {
unlock();
}
}
public V put(K key, V value) {
if (value == null)
throw new NullPointerException();
int hash = hash(key.hashCode());
return segmentFor(hash).put(key, hash, value, false);
}
V 只是 Entry.value 的快照。 Entry 可能尚未完全构建(考虑之前 Java 内存模型中的双重检查锁问题)并且它可能为空。虽然这只是一个极端的情况,但 JRE 必须确保它有效,所以有你的 readValueUnderLock
.
PS:还是跟上时间比较好。 Java 正在发展,Java 9 将在几个月后推出。它的代码库发生了一些巨大的变化。用过时的知识填满你的头脑可能不是一个好主意。
在JDK1.6
阅读ConcurrentHashMap
的源码时,发现readValueUnderLock(e)
无法访问,因为put方法已经检查了值:if value is null,它必须抛出 NullPointerException
。所以我认为可能有问题,但我不确定它是什么。如果有人能回答我,我将不胜感激!
一些源代码在这里:
V get(Object key, int hash) {
if (count != 0) { // read-volatile
HashEntry<K,V> e = getFirst(hash);
while (e != null) {
if (e.hash == hash && key.equals(e.key)) {
V v = e.value;
if (v != null)
return v;
return readValueUnderLock(e); // recheck
}
e = e.next;
}
}
return null;
}
V readValueUnderLock(HashEntry<K,V> e) {
lock();
try {
return e.value;
} finally {
unlock();
}
}
public V put(K key, V value) {
if (value == null)
throw new NullPointerException();
int hash = hash(key.hashCode());
return segmentFor(hash).put(key, hash, value, false);
}
V 只是 Entry.value 的快照。 Entry 可能尚未完全构建(考虑之前 Java 内存模型中的双重检查锁问题)并且它可能为空。虽然这只是一个极端的情况,但 JRE 必须确保它有效,所以有你的 readValueUnderLock
.
PS:还是跟上时间比较好。 Java 正在发展,Java 9 将在几个月后推出。它的代码库发生了一些巨大的变化。用过时的知识填满你的头脑可能不是一个好主意。