亚洲视频二区_亚洲欧洲日本天天堂在线观看_日韩一区二区在线观看_中文字幕不卡一区

公告:魔扣目錄網(wǎng)為廣大站長提供免費(fèi)收錄網(wǎng)站服務(wù),提交前請(qǐng)做好本站友鏈:【 網(wǎng)站目錄:http://www.430618.com 】, 免友鏈快審服務(wù)(50元/站),

點(diǎn)擊這里在線咨詢客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會(huì)員:747

 

0. HashMap 簡單說幾句

我們?cè)趯W(xué)習(xí) HashMap 的時(shí)候,都知道 HashMap 是非線程安全的,同時(shí)我們知道 HashTable 是線程安全的,因?yàn)槔锩娴姆椒ㄊ褂昧?synchronized 進(jìn)行同步。

但是 HashMap 為什么是非線程安全的呢?難道僅僅就是因?yàn)閮?nèi)部的方法沒有 synchronized 關(guān)鍵字修飾嗎?這篇文章主要來分析一下原因。

我們知道 HashMap 底層是一個(gè) Entry 數(shù)組,當(dāng)發(fā)生 hash 沖突的時(shí)候,HashMap 是采用鏈表的方式來解決的,在對(duì)應(yīng)的數(shù)組位置存放鏈表的頭結(jié)點(diǎn)。對(duì)鏈表而言,新加入的節(jié)點(diǎn)會(huì)從頭結(jié)點(diǎn)加入。

為什么說 HashMap 是非線程安全的?

 

HashMap為什么線程不安全,多線程并發(fā)的時(shí)候在什么情況下可能出現(xiàn)問題?

JAVAdoc中關(guān)于hashmap的一段描述如下:

此實(shí)現(xiàn)不是同步的。如果多個(gè)線程同時(shí)訪問一個(gè)哈希映射,而其中至少一個(gè)線程從結(jié)構(gòu)上修改了該映射,則它必須 保持外部同步。(結(jié)構(gòu)上的修改是指添加或刪除一個(gè)或多個(gè)映射關(guān)系的任何操作;僅改變與實(shí)例已經(jīng)包含的鍵關(guān)聯(lián)的值不是結(jié)構(gòu)上的修改。)這一般通過對(duì)自然封裝該映射的對(duì)象進(jìn)行同步操作來完成。如果使用 Collections.synchronizedMap 方法來“包裝”該映射。最好在創(chuàng)建時(shí)完成這一操作,以防止對(duì)映射進(jìn)行意外的非同步訪問,如下所示:

Map map = Collections.synchronizedMap(new HashMap<>());

1. HashMap 在插入的時(shí)候

為什么說 HashMap 是非線程安全的?

 

在Hashmap做put操作的時(shí)候會(huì)調(diào)用到以上的addEntry方法。

現(xiàn)在假如A線程和B線程同時(shí)對(duì)同一個(gè)數(shù)組位置調(diào)用addEntry,兩個(gè)線程會(huì)同時(shí)得到現(xiàn)在的頭結(jié)點(diǎn),然后A寫入新的頭結(jié)點(diǎn)之后,B也寫入新的頭結(jié)點(diǎn),那B的寫入操作就會(huì)覆蓋A的寫入操作造成A的寫入操作丟失。

2. HashMap 在擴(kuò)容的時(shí)候

addEntry中當(dāng)加入新的鍵值對(duì)后鍵值對(duì)總數(shù)量超過門限值的時(shí)候會(huì)調(diào)用一個(gè)resize操作,代碼如下:

為什么說 HashMap 是非線程安全的?

 

這個(gè)操作會(huì)新生成一個(gè)新的容量的數(shù)組,然后對(duì)原數(shù)組的所有鍵值對(duì)重新進(jìn)行計(jì)算和寫入新的數(shù)組,之后指向新生成的數(shù)組。

HashMap 有個(gè)擴(kuò)容的操作,這個(gè)操作會(huì)新生成一個(gè)新的容量的數(shù)組,然后對(duì)原數(shù)組的所有鍵值對(duì)重新進(jìn)行計(jì)算和寫入新的數(shù)組,之后指向新生成的數(shù)組。

那么問題來了,當(dāng)多個(gè)線程同時(shí)進(jìn)來,檢測(cè)到總數(shù)量超過門限值的時(shí)候就會(huì)同時(shí)調(diào)用 resize 操作,各自生成新的數(shù)組并 rehash 后賦給該 map 底層的數(shù)組,結(jié)果最終只有最后一個(gè)線程生成的新數(shù)組被賦給該 map 底層,其他線程的均會(huì)丟失。而且當(dāng)某些線程已經(jīng)完成賦值而其他線程剛開始的時(shí)候,就會(huì)用已經(jīng)被賦值的table作為原始數(shù)組,這樣也會(huì)有問題。

其他地方還有很多可能會(huì)出現(xiàn)線程安全問題,我就不一一列舉了,總之 HashMap 是非線程安全的,有并發(fā)問題時(shí),建議使用 ConcrrentHashMap。

分享到:
標(biāo)簽:HashMap
用戶無頭像

網(wǎng)友整理

注冊(cè)時(shí)間:

網(wǎng)站:5 個(gè)   小程序:0 個(gè)  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會(huì)員

趕快注冊(cè)賬號(hào),推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨(dú)大挑戰(zhàn)2018-06-03

數(shù)獨(dú)一種數(shù)學(xué)游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學(xué)四六

運(yùn)動(dòng)步數(shù)有氧達(dá)人2018-06-03

記錄運(yùn)動(dòng)步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓(xùn)練成績?cè)u(píng)定2018-06-03

通用課目體育訓(xùn)練成績?cè)u(píng)定