Why readValueUnderLock(e) exist in ConcurrentHashMap’s get method?

185 views Asked by At

When I read the source code of ConcurrentHashMap at JDK1.6, I found that readValueUnderLock(e) can't be reached, because the put method has checked the value: if value is null, it must throw NullPointerException. So I think there may be something wrong but i'm not sure what it is. I'll be grateful if someone can answer me!

some source code here:

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);
}
1

There are 1 answers

5
glee8e On BEST ANSWER

V is just a snapshot of the Entry.value. The Entry may not be fully constructed yet (consider the double-check lock issue in previous Java Memory Model) and it could be null. While this is just a extreme edge case, JRE has to make sure this works, so there is your readValueUnderLock.

PS: It's better to keep up with the time. Java is evolving and Java 9 is coming in several months. There has been some tremendous changes in its codebase. Filling up your head with obsolete knowledge may not be a good idea.