自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

為什么ConcurrentHashMap不允許插入Null值?

開發(fā) 前端
我們?cè)谠创a中似乎已經(jīng)找到了原因,你可以這樣回答面試官,說JDK源碼就是這么規(guī)定的。然而,這個(gè)原因是不能說服面試官的,雖然,源碼是這樣設(shè)計(jì)的,我們要思考的是,這樣設(shè)計(jì)背后更深層次的原因。

在Java語言中,給ConcurrentHashMap和Hashtable這些線程安全的集合中的Key或者Value插入 null(空) 值的會(huì)報(bào)空指針異常,但是單線程操作的HashMap又允許 Key 或者 Value 插入 null(空) 值。這到底是為什么呢?

1.探尋源碼

為了找到原因,我們先來看這樣一段源碼片段,打開ConcurrentHashMap的putVal()方法,源碼中第一句就非常明確地做了判斷,如果 Key 或者 Value 為 null(空) 值,就直接拋出空指針異常。

我們?cè)谠创a中似乎已經(jīng)找到了原因,你可以這樣回答面試官,說JDK源碼就是這么規(guī)定的。然而,這個(gè)原因是不能說服面試官的,雖然,源碼是這樣設(shè)計(jì)的,我們要思考的是,這樣設(shè)計(jì)背后更深層次的原因。

那到底為什么ConcurrentHashMap不允許插入 null (空)值,HashMap又允許插入呢?

2.歧義問題

因?yàn)榻oConcurrentHashMap中插入 null (空)值會(huì)存在歧義。我們可以假設(shè)ConcurrentHashMap允許插入 null(空) 值,那么,我們?nèi)≈档臅r(shí)候會(huì)出現(xiàn)兩種結(jié)果:

1)值沒有在集合中,所以返回的結(jié)果就是 null (空);

2)值就是 null(空),所以返回的結(jié)果就是它原本的 null(空) 值。

這就產(chǎn)生了歧義問題。

那HashMap允許插入 null(空) 值,難道它就不擔(dān)心出現(xiàn)歧義嗎?這是因?yàn)镠ashMap的設(shè)計(jì)是給單線程使用的,所以如果取到 null(空) 值,我們可以通過HashMap的 containsKey(key)方 法來區(qū)分這個(gè) null(空) 值到底是插入值是 null(空),還是本就沒有才返回的 null(空) 值。

而 ConcurrentHashMap 就不一樣了,因?yàn)?ConcurrentHashMap 是在多線程場景下使用的,它的情況更加復(fù)雜。

舉個(gè)例子,現(xiàn)在有線程T1調(diào)用了 ConcurrentHashMap 的 containsKey(key) 方法,我們期望返回的結(jié)果是false,也就是說,T1并沒有往ConcurrentHashMap中 put null(空)值。

但是,恰恰出了個(gè)意外,在線程T1還沒有得到返回結(jié)果之前,線程T2又調(diào)用了ConcurrentHashMap 的 put() 方法,插入了一個(gè)Key,并且存入的Value是 null(空) 值。那么,線程T1 最終得到的返回結(jié)果就變成 true 了。

顯然,這個(gè)結(jié)果和我們之前期望的 false 完全不一致。

也就是說,在多線程的復(fù)雜情況下,我們多線程的復(fù)雜情況下,到底是插入的 null(空) 值,還是本就沒有才返回的 null(空) 值。也就是說,產(chǎn)生的歧義不能被 證 偽,

3.作者回復(fù)

對(duì)于 ConcurrentHashMap 不允許插入 null 值的問題,有人問過 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 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 認(rèn)為這樣設(shè)計(jì)最主要的原因是:不容忍在并發(fā)場景下出現(xiàn)歧義!

4.總結(jié)

ConcurrentHashMap在源碼中加入不允許插入 null (空) 值的設(shè)計(jì),主要目的是為了防止并發(fā)場景下的歧義問題。

以上就是我對(duì)關(guān)于ConcurrentHashMap為什么不允許插入 null (空) 值的解答,聽懂的小伙伴,請(qǐng)關(guān)注點(diǎn)個(gè)贊,下次不迷路。

責(zé)任編輯:武曉燕 來源: Tom彈架構(gòu)
相關(guān)推薦

2022-01-27 07:02:52

JavaHashMap單線程

2023-08-22 20:43:09

HashMap單線程null

2009-06-18 10:47:44

java接口定義變量

2024-09-03 09:45:36

2021-08-23 12:54:12

開發(fā)技能代碼

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蘋果降級(jí)

2011-04-22 10:15:56

Novell專利

2010-06-01 16:12:00

2011-03-01 14:12:12

FreebsdProftpd

2010-11-02 15:08:40

設(shè)置db2主鍵

2025-03-27 01:10:00

HashMap分段鎖CAS

2010-05-20 13:03:52

IIS父路徑

2024-06-06 08:10:30

多線程Mapnull

2023-05-09 10:05:24

HashMapNull

2009-09-22 15:54:42

CCIE筆試

2012-01-04 21:24:13

Android 4.0

2023-05-23 08:54:43

SRESLO運(yùn)營

2010-11-11 16:53:28

SQL Server視
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)