HashMap高併發下存在的問題

原文連接:https://blog.csdn.net/bjwfm2011/article/details/81076736數組

一、什麼是HashMap?併發

    HashMap底層原理高併發

      HashMap是存儲鍵值對(key-value)的集合,每一個鍵值對也叫作Entry,這些Entry分散存儲在一個數組中,這個數組能夠稱爲HashMap的主幹。.net

二、HashMap在高併發下會產生的狀況blog

  在分析高併發狀況以前,須要搞清楚ReHash這個概念。(ReHash是HashMap在擴容時候的一個步驟)ci

   HashMap的容量是有限的,當通過屢次元素插入,使得HashMap達到必定的飽和度時,key映射位置發生衝突的概率會逐漸提升,這時候HashMap須要擴展它的長度,就是進行Resize。it

影響Resize的因素有兩個原理

  • Capacity    HashMap的當前長度;
  • LoadFactor HashMap的負載因子,默認值是0.75f;

衡量HashMap是否進行Resize的條件:擴展

  HashMap.Size >= Capacity * LoadFactor遍歷

三、HashMap的Resize具體作了哪些事情呢?HashMap不是簡單的把長度擴大,而是通過了下面兩個步驟:

  

  • 擴容:建立一個新的Entry空數組,長度是原數組的2倍。
  • ReHash:遍歷原Entry數組,把全部的Entry從新Hash到新數組。爲何要從新Hash呢?由於長度擴大之後,Hash的規則也隨之改變。

Hash公式:index =  HashCode(Key) &  (Length - 1)

當原數組長度爲8時,Hash運算是和111B作與運算;新數組長度爲16,Hash運算是和1111B作與運算。Hash結果顯然不一樣。

Resize前的HashMap:

   

Resize後的HashMap:

ReHash的Java代碼以下:

相關文章
相關標籤/搜索