成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

為什么ConcurrentHashMap不允許插null?

開發 前端
在 Java 語言中,HashMap 這種單線程下使用的集合是可以設置 null 值的,而并發集合如 ConcurrentHashMap 或 Hashtable 是不允許給 key 或 value 設置 null 值的,這是 JDK 源碼層面直接實現的,這樣設計的目的主要是為了防止并發場景下的歧義問題。

在 Java 語言中,ConcurrentHashMap 和 Hashtable 這些線程安全的集合是不允許 key 或 value 插入 null 值的,而 HashMap 又允許 key 或 value 插入 null 值,這到底是為什么呢?

null 值插入演示

首先給 HashMap 插入 null 值,實現代碼如下:

HashMap<String, Object> map = new HashMap();
// 插入 null 值
map.put(null, null);
if (map.containsKey(null)) {
    System.out.println("存在 null");
} else {
    System.out.println("不存在 null");
}

以上程序的執行結果如下:

圖片圖片

從上述結果可以看出,HashMap 是允許 key 或 value 插入 null 值的。接著我們使用同樣的方式嘗試給 ConcurrentHashMap 的 key 和 value 插入 null 值,實現代碼如下:

圖片圖片

編譯階段沒有報錯,執行以上程序,得到的結果如下:

圖片圖片

從上述報錯信息可以看出,使用 ConcurrentHashMap 是不能插入 null 值的,否者程序在運行期間就會報空指針異常。

PS:Hashtable 使用與 ConcurrentHashMap 類似,這里就不再重復演示了。

ConcurrentHashMap 源碼分析

為了尋找報錯的原因,我們嘗試打開 ConcurrentHashMap 的源碼一探究竟。打開 ConcurrentHashMap 添加元素的方法 put 實現源碼如下:

圖片圖片

從上述源碼可以看出,在添加方法的第一句就加了判斷:如果 key 值為 null 或者是 value 值為 null,就直接拋出異常 NullPointerException 空指針異常,這就是咱們前面程序報錯的原因了。

探索最終原因

通過上面源碼分析,我們似乎已經找到了 ConcurrentHashMap 不允許插入 null 值的原因,用一句話概括就是:烏龜的屁股“規定”!然而,這個原因是不能說服面試官的,雖然源碼是這樣設計的,但我們要思考的是,這樣設計背后更深層次的原因,為什么 ConcurrentHashMap 不允許插入 null?而 HashMap 又允許插入 null 呢?

二義性問題

所謂的二義性問題是指含義不清或不明確。我們假設 ConcurrentHashMap 允許插入 null,那么此時就會有二義性問題,它的二義性含義有兩個:

  1. 值沒有在集合中,所以返回 null。
  2. 值就是 null,所以返回的就是它原本的 null 值。

可以看出這就是 ConcurrentHashMap 的二義性問題,那為什么 HashMap 就不怕二義性問題呢?

可證偽的 HashMap

上面說到 HashMap 是不怕二義性問題的,為什么呢?這是因為 HashMap 的設計是給單線程使用的,所以如果查詢到了 null 值,我們可以通過 hashMap.containsKey(key) 的方法來區分這個 null 值到底是存入的 null?還是壓根不存在的 null?這樣二義性問題就得到了解決,所以 HashMap 不怕二義性問題。

不可證偽的 ConcurrentHashMap

而 ConcurrentHashMap 就不一樣了,因為 ConcurrentHashMap 使用的場景是多線程,所以它的情況更加復雜。我們假設 ConcurrentHashMap 可以存入 null 值,有這樣一個場景,現在有一個線程 A 調用了 concurrentHashMap.containsKey(key),我們期望返回的結果是 false,但在我們調用 concurrentHashMap.containsKey(key) 之后,未返回結果之前,線程 B 又調用了 concurrentHashMap.put(key,null) 存入了 null 值,那么線程 A 最終返回的結果就是 true 了,這個結果和我們之前預想的 false 完全不一樣。也就是說,多線程的狀況非常復雜,我們沒辦法判斷某一個時刻返回的 null 值,到底是值為 null,還是壓根就不存在,也就是二義性問題不可被證偽,所以 ConcurrentHashMap 才會在源碼中這樣設計,直接杜絕 key 或 value 為 null 的歧義問題。

ConcurrentHashMap 設計者的回答

對于 ConcurrentHashMap 不允許插入 null 值的問題,有人問過 ConcurrentHashMap 的作者 Doug Lea,以下是他回復的郵件內容:

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 allowing nulls in Maps (also Sets) is an open invitation for programs to contain errors that remain undetected until they break at just the wrong time. (Whether to allow nulls even in non-concurrent Maps/Sets is one of the few design issues surrounding Collections that Josh Bloch and I have long disagreed about.)

It is very difficult to check for null keys and values in my entire application .

Would it be easier to declare somewhere     static final Object NULL = new Object(); and replace all use of nulls in uses of maps with NULL? -Doug

以上信件的主要意思是,Doug Lea 認為這樣設計最主要的原因是:不容忍在并發場景下出現歧義!

總結

在 Java 語言中,HashMap 這種單線程下使用的集合是可以設置 null 值的,而并發集合如 ConcurrentHashMap 或 Hashtable 是不允許給 key 或 value 設置 null 值的,這是 JDK 源碼層面直接實現的,這樣設計的目的主要是為了防止并發場景下的歧義問題。

參考文檔

cnblogs.com/fanguangdexiaoyuer/p/12335921.html

責任編輯:武曉燕 來源: Java面試真題解析
相關推薦

2022-05-08 18:18:40

JDKValueHashMap

2022-01-27 07:02:52

JavaHashMap單線程

2009-06-18 10:47:44

java接口定義變量

2024-09-03 09:45:36

2021-08-23 12:54:12

開發技能代碼

2015-08-17 10:16:00

CentOSDocker命令root

2014-06-30 14:53:49

Android定制google

2020-08-20 11:12:14

iOS 13.6蘋果降級

2011-04-22 10:15:56

Novell專利

2025-03-27 01:10:00

HashMap分段鎖CAS

2010-06-01 16:12:00

2010-11-02 15:08:40

設置db2主鍵

2011-03-01 14:12:12

FreebsdProftpd

2010-05-20 13:03:52

IIS父路徑

2009-09-22 15:54:42

CCIE筆試

2012-01-04 21:24:13

Android 4.0

2023-05-23 08:54:43

SRESLO運營

2010-11-11 16:53:28

SQL Server視

2023-05-09 10:05:24

HashMapNull

2018-06-13 10:08:05

蘋果數據開發者
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 毛片a | 国内精品在线视频 | 香蕉一区 | 免费观看黄网站 | 久久亚洲春色中文字幕久久久 | 精品自拍视频在线观看 | 精品国产18久久久久久二百 | 欧美日韩综合一区 | 日韩综合网| 密室大逃脱第六季大神版在线观看 | 91精品国产一区 | 久久在线 | 国产精品成人一区二区三区 | 欧美精品一区二区三区在线播放 | 又爽又黄axxx片免费观看 | 免费久久网站 | 欧美aaa级 | 午夜黄色 | 成人精品国产免费网站 | 亚洲综合三区 | 精品国产综合 | 特黄一级 | 亚洲成av| 久热精品在线观看视频 | 在线观看视频亚洲 | 在线免费观看视频你懂的 | 99精品视频免费观看 | 亚洲国产一区在线 | 日韩一级一区 | 中文字幕在线精品 | 亚洲精品久久久久中文字幕欢迎你 | 黑色丝袜三级在线播放 | 日韩中文字幕 | 日本激情视频在线播放 | 国产精品永久免费视频 | 亚州一区二区三区 | 国产精品人人做人人爽 | 伊人久久综合 | 久草在线高清 | www.成人免费视频 | 免费国产黄网站在线观看视频 |