Java的ConcurrentHashMap中不能存儲(chǔ)null的原因解析
眾所周知,在Java中Map可以存儲(chǔ)null,而ConcurrentHashMap不能存儲(chǔ)null值,那么為什么呢?
一、先出源碼出發(fā)

put方法點(diǎn)進(jìn)去~

@throws NullPointerException if the specified key or value is null and this map does not permit null keys or values
可以清晰的看到源碼中規(guī)定,ConcurrentHashMap是不可以存儲(chǔ)null值的。
二、那么究竟這是為什么呢?
可以先具體的了解一下ConcurrentHashMap。
與HashMap一樣,ConcurrentHashMap也是一個(gè)基于散列的Map,但它使用了一種完全不同的加鎖策略來(lái)提供更高的并發(fā)性和伸縮性。ConcurrentHashMap并不是將每個(gè)方法都在同一個(gè)鎖上同步并使得每次只能有一個(gè)線程訪問(wèn)容器,而是使用一種更細(xì)的加鎖機(jī)制來(lái)實(shí)現(xiàn)更大程度的共享,這種機(jī)制成為分段鎖。在這種機(jī)制中,任意數(shù)量的讀取線程可以并發(fā)地訪問(wèn)Map,執(zhí)行讀取操作的線程和執(zhí)行寫入操作的線程可以并發(fā)地訪問(wèn)Map,并且一定數(shù)量的寫入線程可以并發(fā)地修改Map。ConcurrentHashMap帶來(lái)的結(jié)果是,在并發(fā)訪問(wèn)環(huán)境下將實(shí)現(xiàn)更高的吞吐量,而在單線程環(huán)境中只損失非常小的性能。
ConcurrentHashMap返回的迭代器具有弱一致性,而并非“及時(shí)失敗”。弱一致性的迭代器可以容忍并發(fā)的修改,當(dāng)創(chuàng)建迭代器時(shí)會(huì)遍歷已有的元素,并可以在迭代器被構(gòu)造后將修改操作反映給容器。ConcurrentHashMap返回的迭代器具有弱一致性,而并非“及時(shí)失敗”。弱一致性的迭代器可以容忍并發(fā)的修改,當(dāng)創(chuàng)建迭代器時(shí)會(huì)遍歷已有的元素,并可以在迭代器被構(gòu)造后將修改操作反映給容器。
三、ConcurrentHashMap 作者 Doug Lea 的郵件
對(duì)于 ConcurrentHashMap 不允許插入 null 值的問(wèn)題,有人問(wèn)過(guò) ConcurrentHashMap 的作者 Doug Lea,以下是他回復(fù)的郵件內(nèi)容:
The main reason that nulls aren’t allowed in ConcurrentMaps
(ConcurrentHashMaps, ConcurrentSkipListMaps) is that ambiguities that
may be just barely tolerable in non-concurrent maps can’t be
accommodated. The main one is that if map.get(key) returns null, you
can’t detect whether the key explicitly maps to null vs the key isn’t
mapped.In a non-concurrent map, you can check this via
map.contains(key),but in a concurrent one, the map might have changed
between calls.Further digressing: I personally think that
allowingnulls in Maps (also Sets) is an open invitation for programsto
contain errors that remain undetected untilthey break at just the
wrong time. (Whether to allow nulls evenin non-concurrent Maps/Sets is
one of the few design issues surroundingCollections that Josh Bloch
and I have long disagreed about.)It is very difficult to check for
null keys and valuesin my entire application .Would it be easier to
declare somewherestatic final Object NULL = new Object();and replace
all use of nulls in uses of maps with NULL?-Doug
以上信件的主要意思是,Doug Lea 認(rèn)為這樣設(shè)計(jì)最主要的原因是:不容忍在并發(fā)場(chǎng)景下出現(xiàn)歧義!
到此這篇關(guān)于Java的ConcurrentHashMap中不能存儲(chǔ)null的原因解析的文章就介紹到這了,更多相關(guān)Java ConcurrentHashMap不能存儲(chǔ)null內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringBoot整合Graylog做日志收集實(shí)現(xiàn)過(guò)程
這篇文章主要為大家介紹了SpringBoot整合Graylog做日志收集實(shí)現(xiàn)過(guò)程詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-12-12
Java?Chassis3應(yīng)用視角的配置管理技術(shù)解密
這篇文章主要為大家介紹了Java?Chassis3應(yīng)用視角的配置管理相關(guān)的機(jī)制和背后故事,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2024-01-01
java中pdf轉(zhuǎn)圖片的實(shí)現(xiàn)方法
下面小編就為大家?guī)?lái)一篇java中pdf轉(zhuǎn)圖片的實(shí)現(xiàn)方法。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-12-12
Java字符串拼接的五種方法及性能比較分析(從執(zhí)行100次到90萬(wàn)次)
字符串拼接一般使用“+”,但是“+”不能滿足大批量數(shù)據(jù)的處理,Java中有以下五種方法處理字符串拼接及性能比較分析,感興趣的可以了解一下2021-12-12

