ConcurrentHashMap

      網友投稿 845 2025-03-31

      ConcurrentHashMap


      為什么要用ConcurrentHashMap

      (1)線程不安全的HashMap

      在多線程環境下,使用HashMap進行put操作會引起死循環,導致CPU利用率接近100%,所以在并發情況下不能使用HashMap。

      HashMap在并發執行put操作時會引起死循環,是因為多線程會導致HashMap的Entry鏈表形成環形數據結構,一旦形成環形數據結構,Entry的next節點永遠不為空,就會產生死循環獲取Entry。

      (2)效率低下的HashTable

      HashTable容器使用synchronized來保證線程安全,但在線程競爭激烈的情況下HashTable的效率非常低下。因為當一個線程訪問HashTable的同步方法,其他線程也訪問HashTable的同步方法時,會進入阻塞或輪詢狀態。如線程1使用put進行元素添加,線程2不但不能使用put方法添加元素,也不能使用get方法來獲取元素,所以競爭越激烈效率越低。

      (3)ConcurrentHashMap的鎖分段技術可有效提升并發訪問率

      HashTable容器在競爭激烈的并發環境下表現出效率低下的原因是所有訪問HashTable的線程都必須競爭同一把鎖,假如容器里有多把鎖,每一把鎖用于鎖容器其中一部分數據,那么當多線程訪問容器里不同數據段的數據時,線程間就不會存在鎖競爭,從而可以有效提高并發訪問效率,這就是ConcurrentHashMap所使用的鎖分段技術。首先將數據分成一段一段地存儲,然后給每一段數據配一把鎖,當一個線程占用鎖訪問其中一個段數據的時候,其他段的數據也能被其他線程訪問。

      ConcurrentHashMap的結構

      ConcurrentHashMap是由Segment數組結構和HashEntry數組結構組成。Segment是一種可重入鎖(ReentrantLock),在ConcurrentHashMap里扮演鎖的角色;HashEntry則用于存儲鍵值對數據。

      ConcurrentHashMap

      一個ConcurrentHashMap里包含一個Segment數組。Segment的結構和HashMap類似,是一種數組和鏈表結構。一個Segment里包含一個HashEntry數組,每個HashEntry是一個鏈表結構的元素,每個Segment守護著一個HashEntry數組里的元素,當對HashEntry數組的數據進行修改時,必須首先獲得與它對應的Segment鎖,

      ConcurrentHashMap的初始化

      ConcurrentHashMap初始化方法是通過initialCapacity、loadFactor和concurrencyLevel等幾個參數來初始化segment數組、段偏移量segmentShift、段掩碼segmentMask和每個segment里的HashEntry數組來實現的。

      ConcurrentHashMap的操作

      由于put方法里需要對共享變量進行寫入操作,所以為了線程安全,在操作共享變量時必須加鎖。put方法首先定位到Segment,然后在Segment里進行插入操作。插入操作需要經歷兩個步驟,第一步判斷是否需要對Segment里的HashEntry數組進行擴容,第二步定位添加元素的位

      置,然后將其放在HashEntry數組里。

      (1)是否需要擴容

      在插入元素前會先判斷Segment里的HashEntry數組是否超過容量(threshold),如果超過閾值,則對數組進行擴容。值得一提的是,Segment的擴容判斷比HashMap更恰當,因為HashMap是在插入元素后判斷元素是否已經到達容量的,如果到達了就進行擴容,但是很有可能擴容

      之后沒有新元素插入,這時HashMap就進行了一次無效的擴容。

      (2)如何擴容

      在擴容的時候,首先會創建一個容量是原來容量兩倍的數組,然后將原數組里的元素進行再散列后插入到新的數組里。為了高效,ConcurrentHashMap不會對整個容器進行擴容,而只對某個segment進行擴容。

      先嘗試2次通過不鎖住Segment的方式來統計各個Segment大小,如果統計的過程中,容器的count發生了變化,則再采用加鎖的方式來統計所有Segment的大小。

      那么ConcurrentHashMap是如何判斷在統計的時候容器是否發生了變化呢?使用modCount變量,在put、remove和clean方法里操作元素前都會將變量modCount進行加1,那么在統計size前后比較modCount是否發生變化,從而得知容器的大小是否發生變化。

      HashMap Java 容器 數據結構

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:《云計算技術系列叢書 云原生分布式存儲基石: etcd深入解析》—2.3.2消息發布和訂閱
      下一篇:Excel VLOOKUP函數實現向左查詢的實例
      相關文章
      亚洲精品影院久久久久久| 亚洲AV日韩精品久久久久| 18gay台湾男同亚洲男同| 亚洲VA成无码人在线观看天堂| 国产亚洲成归v人片在线观看| 亚洲高清最新av网站| 国产亚洲蜜芽精品久久| 亚洲国产香蕉人人爽成AV片久久| 久久水蜜桃亚洲AV无码精品| 亚洲AV成人无码网站| 亚洲精华国产精华精华液好用| 亚洲av无码专区青青草原| 国产成人人综合亚洲欧美丁香花 | 久久久久亚洲av无码专区蜜芽| 国产AV无码专区亚洲AVJULIA| 亚洲αv在线精品糸列| 亚洲AV无码专区在线播放中文| 亚洲精品国产字幕久久不卡 | 亚洲日本VA中文字幕久久道具| 亚洲乱亚洲乱妇24p| 国产精品自拍亚洲| 亚洲人成无码久久电影网站| 亚洲人成电影网站国产精品| 自拍偷自拍亚洲精品被多人伦好爽| 亚洲综合无码精品一区二区三区| 国产亚洲3p无码一区二区| 无码欧精品亚洲日韩一区| 亚洲精品国产肉丝袜久久| 亚洲av永久无码精品三区在线4 | 亚洲av无码成人精品区一本二本| 成人亚洲国产精品久久| 爱情岛论坛网亚洲品质自拍| 亚洲熟妇av一区二区三区| 久久青青草原亚洲AV无码麻豆 | 久久亚洲AV无码精品色午夜| 亚洲午夜国产精品| 亚洲精品无码中文久久字幕| 亚洲成av人片不卡无码久久| 中文字幕久久亚洲一区| 婷婷亚洲综合五月天小说 | 伊人久久精品亚洲午夜|