<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

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

          共 1251字,需瀏覽 3分鐘

           ·

          2021-07-09 00:00

          ????關(guān)注后回復(fù) “進(jìn)群” ,拉你進(jìn)程序員交流群????

          作者丨倪升武

          來源丨武哥聊編程


          我們在學(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 是采用鏈表的方式來解決的,在對應(yīng)的數(shù)組位置存放鏈表的頭結(jié)點(diǎn)。對鏈表而言,新加入的節(jié)點(diǎn)會(huì)從頭結(jié)點(diǎn)加入。


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


          現(xiàn)在假如 A 線程和 B 線程同時(shí)進(jìn)行插入操作,然后計(jì)算出了相同的哈希值對應(yīng)了相同的數(shù)組位置,因?yàn)榇藭r(shí)該位置還沒數(shù)據(jù),然后對同一個(gè)數(shù)組位置,兩個(gè)線程會(huì)同時(shí)得到現(xiàn)在的頭結(jié)點(diǎn),然后 A 寫入新的頭結(jié)點(diǎn)之后,B 也寫入新的頭結(jié)點(diǎn),那B的寫入操作就會(huì)覆蓋 A 的寫入操作造成 A 的寫入操作丟失。


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


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


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


          3. HashMap 在刪除數(shù)據(jù)的時(shí)候


          刪除這一塊可能會(huì)出現(xiàn)兩種線程安全問題,第一種是一個(gè)線程判斷得到了指定的數(shù)組位置i并進(jìn)入了循環(huán),此時(shí),另一個(gè)線程也在同樣的位置已經(jīng)刪掉了i位置的那個(gè)數(shù)據(jù)了,然后第一個(gè)線程那邊就沒了。但是刪除的話,沒了倒問題不大。


          再看另一種情況,當(dāng)多個(gè)線程同時(shí)操作同一個(gè)數(shù)組位置的時(shí)候,也都會(huì)先取得現(xiàn)在狀態(tài)下該位置存儲的頭結(jié)點(diǎn),然后各自去進(jìn)行計(jì)算操作,之后再把結(jié)果寫會(huì)到該數(shù)組位置去,其實(shí)寫回的時(shí)候可能其他的線程已經(jīng)就把這個(gè)位置給修改過了,就會(huì)覆蓋其他線程的修改。


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


          -End-

          最近有一些小伙伴,讓我?guī)兔φ乙恍?nbsp;面試題 資料,于是我翻遍了收藏的 5T 資料后,匯總整理出來,可以說是程序員面試必備!所有資料都整理到網(wǎng)盤了,歡迎下載!

          點(diǎn)擊??卡片,關(guān)注后回復(fù)【面試題】即可獲取

          在看點(diǎn)這里好文分享給更多人↓↓

          瀏覽 33
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  日韩精品免费无码中文字幕 | 豆花在线观看 | 四虎久久影院 | 国产极品se婷婷 | 日本免费黄视频 |