e.hash == hash && key.equals(e.key)
前面这一句说明了表里有这个key的,你看看put方法,当value为null的时候是会跑出异常的:
key
put
value
null
public V put(K key, V value) { Segment<K,V> s; if (value == null) throw new NullPointerException(); int hash = hash(key); int j = (hash >>> segmentShift) & segmentMask; if ((s = (Segment<K,V>)UNSAFE.getObject // nonvolatile; recheck (segments, (j << SSHIFT) + SBASE)) == null) // in ensureSegment s = ensureSegment(j); return s.put(key, hash, value, false); }
我这是高版本的,可能和你的不一样,但是也是值也是不能为空的。所以:
if (v != null) return v; return readValueUnderLock(e); // recheck
不为空可以直接返回,如果为空则说明有其他线程在操作它。所以就加了一句。
public V get(Object key) { Segment<K,V> s; // manually integrate access methods to reduce overhead HashEntry<K,V>[] tab; int h = hash(key); long u = (((h >>> segmentShift) & segmentMask) << SSHIFT) + SBASE; if ((s = (Segment<K,V>)UNSAFE.getObjectVolatile(segments, u)) != null && (tab = s.table) != null) { for (HashEntry<K,V> e = (HashEntry<K,V>) UNSAFE.getObjectVolatile (tab, ((long)(((tab.length - 1) & h)) << TSHIFT) + TBASE); e != null; e = e.next) { K k; if ((k = e.key) == key || (e.hash == h && key.equals(k))) return e.value; } } return null; }
现在版本的get方法把HashEntry<K,V> e弄成UNSAFE.getObjectVolatile()获取,像是volatile的了
get
HashEntry<K,V> e
UNSAFE.getObjectVolatile()
volatile
楼主可以把JDK升级一下,我用的1.8找了一下,没发现这段代码在ConcurrentHashMap中。
1.8
ConcurrentHashMap
对象初始的时候就是null,这个null并不是在程序中特意赋值的。
前面这一句说明了表里有这个
key
的,你看看put
方法,当value
为null
的时候是会跑出异常的:我这是高版本的,可能和你的不一样,但是也是值也是不能为空的。
所以:
不为空可以直接返回,如果为空则说明有其他线程在操作它。所以就加了一句。
现在版本的
get
方法把HashEntry<K,V> e
弄成UNSAFE.getObjectVolatile()
获取,像是volatile
的了楼主可以把JDK升级一下,我用的
1.8
找了一下,没发现这段代码在ConcurrentHashMap
中。对象初始的时候就是null,这个null并不是在程序中特意赋值的。