1. 程式人生 > >HashMapHashTableConcurrentHashMap的原理與區別

HashMapHashTableConcurrentHashMap的原理與區別

htable 分段 但是 最新 底層 RR 插入元素 擴容 volatil

HashTable:

  • 底層數組+鏈表,key與value都不能為null,線程安全,實現線程安全的方式是在修改數據時鎖住整個HashTable,效率低。
  • 初始size為11,擴容:newsize = oldsize*2 + 1
  • 計算index的方法:index = (hash & 0x7FFFFFFF)%tab.length

HashMap:

  • 底層數組+鏈表實現,可以存儲null鍵和null值,線程不安全
  • 初始size為16,擴容newsize = oldsize*2,size一定為2的n次冪
  • 擴容針對整個Map,每次擴容時,原來數組中的元素依次重新計算存放位置,並重新插入
  • 插入元素後才判斷該不該擴容,有可能無效擴容
  • 當map中的元素總數超過Entry數組75%,觸發擴容操作,為了減少鏈表的長度,元素分配更均勻
  • 計算index的方法:index = hash&(tab.length - 1)

ConcurrentHashMap

  • 底層采用分段的數組+鏈表實現,線程安全
  • 通過把整個Map分為N個Segment,可以提供相同的線程安全,但是效率提升N倍,默認提升16倍。(讀操作不加鎖,由於HashEntry的value變量是 volatile的,也能保證讀取到最新的值。)
  • Hashtable的synchronized是針對整張Hash表的,即每次鎖住整張表讓線程獨占,ConcurrentHashMap允許多個修改操作並發進行,其關鍵在於使用了鎖分離技術
  • 有些方法需要跨段,比如size()和containsValue(),它們可能需要鎖定整個表而而不僅僅是某個段,這需要按順序鎖定所有段,操作完畢後,又按順序釋放所有段的鎖
  • 擴容:段內擴容(段內元素超過該段對應Entry數組長度的75%觸發擴容,不會對整個Map進行擴容),插入前檢測需不需要擴容,有效避免無效擴容

HashMap\HashTable\ConcurrentHashMap的原理與區別