美團(tuán)太細(xì)了,HashMap可以存Null,ConcurrentHashMap不可以,為什么?

我們知道,ConcurrentHashMap在使用時,和HashMap有一個比較大的區(qū)別,那就是HashMap中,null可以作為鍵或者值都可以。而在ConcurrentHashMap中,key和value都不允許為null。
那么,為什么呢?為啥ConcurrentHashMap要設(shè)計成這樣的呢?
關(guān)于這個問題,其實最有發(fā)言權(quán)的就是ConcurrentHashMap的作者——Doug Lea。
他自己曾經(jīng)出面解釋過這個問題,內(nèi)容如下(原文地址已經(jīng)打不開了,大家將就著看一下截圖吧) :

主要意思就是說:
ConcurrentMap(如ConcurrentHashMap、ConcurrentSkipListMap)不允許使用null值的主要原因是,在非并發(fā)的Map中(如HashMap),是可以容忍模糊性(二義性)的,而在并發(fā)Map中是無法容忍的。
假如說,所有的Map都支持null的話,那么map.get(key)就可以返回null,但是,這時候就會存在一個不確定性,當(dāng)你拿到null的時候,你是不知道他是因為本來就存了一個null進(jìn)去還是說就是因為沒找到而返回了null。
在HashMap中,因為它的設(shè)計就是給單線程用的,所以當(dāng)我們map.get(key)返回null的時候,我們是可以通過map.contains(key)檢查來進(jìn)行檢測的,如果它返回true,則認(rèn)為是存了一個null,否則就是因為沒找到而返回了null。
但是,像ConcurrentHashMap,它是為并發(fā)而生的,它是要用在并發(fā)場景中的,當(dāng)我們map.get(key)返回null的時候,是沒辦法通過通過map.contains(key)檢查來準(zhǔn)確的檢測,因為在檢測過程中可能會被其他線程鎖修改,而導(dǎo)致檢測結(jié)果并不可靠。
所以,為了讓ConcurrentHashMap的語義更加準(zhǔn)確,不存在二義性的問題,他就不支持null。

























