深入了解HashMap的底層原理

深入了解HashMap的底層原理

各位java開發(fā)的同學(xué)肯定對HashMap并不陌生,它是一種非常常見的數(shù)據(jù)結(jié)構(gòu),可是大家真的對它十分了解嗎?知道它底層設(shè)計的原型和思路嗎?


  • 什么是HashMap
    HashMap是一個存儲K-V鍵值對的集合,每一個鍵值對叫做Entry。這些鍵值對存儲在一個數(shù)組當(dāng)中,這個數(shù)組就是HashMap的主要組成部分。
    使用HashMap主要的方法有兩個Put()和Get()。
    1.Put方法的原理
    當(dāng)調(diào)用Put方法時需要使用Hash函數(shù)來確定Entry在數(shù)組中的位置(index)
    index=Hash("XX")
    假設(shè)index是0,則把“XX”放到數(shù)組的第一個位置上。
    但是如果隨著數(shù)據(jù)的不斷增多,就很容易出現(xiàn)相同的index,這樣就需要通過使用鏈表來解決index沖突的問題。因此HashMap數(shù)組的每一個元素既是一個Entry對象也是鏈表的頭節(jié)點。每一個Entry對象通過Next指針指向它的下一個Entry節(jié)點。這樣如果index再沖突的時候,只需要插入到對應(yīng)的鏈表下即可。
    2.Get方法原理
    使用Get方法時傳入key來獲取value時,同樣會使用Hash函數(shù)對key做一次hash映射,得到對應(yīng)的index,通過index去數(shù)組對應(yīng)的位置上取第一個值和key做比較,如果不是想要的key則順著鏈表取下一個值,直到得到正確的結(jié)果。

  • 為什么老是說HashMap是線程不安全的
    HashMap的容量是有限的,在經(jīng)過多次元素的插入后,key的hash映射發(fā)生沖突的幾率就逐漸提高。這個時候就需要擴展HashMap的長度,也就是進(jìn)行Resize。
    Resize的步驟
    1.擴容
    擴容就是創(chuàng)建一個新的Entry空數(shù)組,長度是原來數(shù)組的兩倍。
    2.ReHash
    ReHash的時候會首先遍歷原來的數(shù)組,把原來數(shù)組所有的Entry重新Hash到新的數(shù)組中。為啥需要把以前的Entry重新Hash一遍呢,因為在數(shù)組的長度增加后,Hash的規(guī)則也相應(yīng)發(fā)生變化。
    此時如果此HashMap達(dá)到了Resize的臨界值,而同時有多個線程在對此HashMap做插入操作時就有可能使HashMap的鏈表出現(xiàn)環(huán)形鏈表,程序就會進(jìn)入死循環(huán)(具體出現(xiàn)環(huán)形鏈表的條件比較苛刻,而且流程非常燒腦)。

  • 線程安全的ConcurrentHashMap
    ConcurrentHashMap是HashMap的升級版,同時兼顧了線程安全和運行的效率。
    ConcurrentHashMap的設(shè)計包含了一個非常重要的數(shù)據(jù)結(jié)構(gòu)Segment
    1.什么是Segment
    Segment本身就是一個HashMap對象,Segment包含一個HashEntry數(shù)組,數(shù)組中的每一個HashEntry既是一個鍵值對,也是鏈表的頭結(jié)點。
    2.ConcurrentHashMap設(shè)計的好處
    每一個Segment都相當(dāng)于一個自治區(qū),讀和寫高度自治,每一個Segment之間互不影響。每一個Segment的寫入是上鎖的,因此對同一個Segment的并發(fā)寫入會被阻塞。這樣既保證了線程安全又降低了鎖的粒度,使并發(fā)操作的效率更高。
    3.ConcurrentHashMap具體的讀寫流程
    Get()方法
    (1):為輸入的Key做Hash運算,得到hash值。
    (2):通過hash值,定位到對應(yīng)的Segment對象。
    (3):再次通過hash值,定位到Segment當(dāng)中數(shù)組的具體位置。
    Put()方法
    (1):為輸入的Key做Hash運算,得到hash值。
    (2):通過hash值,定位到對應(yīng)的Segment對象
    (3):再次通過hash值,定位到Segment當(dāng)中數(shù)組的具體位置。
    (4):插入或覆蓋HashEntry對象。
    (5):釋放鎖。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容