ConcurrentHashMap和Collections.synchronizedMap(Map)有什麼區別?

我有一個地圖,該地圖將同時被多個線程修改。 java

Java API中彷佛有三種不一樣的同步Map實現: 安全

  • Hashtable
  • Collections.synchronizedMap(Map)
  • ConcurrentHashMap

據我瞭解, Hashtable是一箇舊的實現(擴展了過期的Dictionary類),後來對其進行了調整以適合Map接口。 雖然它同步的,但彷佛存在嚴重的可伸縮性問題 ,所以不建議用於新項目。 併發

可是其餘兩個呢? Collections.synchronizedMap(Map)ConcurrentHashMap返回的Collections.synchronizedMap(Map)之間有什麼區別? 哪種適合哪一種狀況? app


#1樓

ConcurrentHashMap ,該鎖將應用於段而不是整個Map。 每一個段都管理本身的內部哈希表。 該鎖僅適用於更新操做。 Collections.synchronizedMap(Map)同步整個地圖。 ide


#2樓

  1. 若是數據一致性很是重要-請使用Hashtable或Collections.synchronizedMap(Map)。
  2. 若是速度/性能很是重要,而且數據更新可能會受到影響,請使用ConcurrentHashMap。

#3樓

╔═══════════════╦═══════════════════╦═══════════════════╦═════════════════════╗
║   Property    ║     HashMap       ║    Hashtable      ║  ConcurrentHashMap  ║
╠═══════════════╬═══════════════════╬═══════════════════╩═════════════════════╣ 
║      Null     ║     allowed       ║              not allowed                ║
║  values/keys  ║                   ║                                         ║
╠═══════════════╬═══════════════════╬═════════════════════════════════════════╣
║Is thread-safe ║       no          ║                  yes                    ║
╠═══════════════╬═══════════════════╬═══════════════════╦═════════════════════╣
║     Lock      ║       not         ║ locks the whole   ║ locks the portion   ║        
║  mechanism    ║    applicable     ║       map         ║                     ║ 
╠═══════════════╬═══════════════════╩═══════════════════╬═════════════════════╣
║   Iterator    ║               fail-fast               ║ weakly consistent   ║ 
╚═══════════════╩═══════════════════════════════════════╩═════════════════════╝

關於鎖定機制: Hashtable 鎖定對象 ,而ConcurrentHashMap 鎖定bucket性能


#4樓

二者之間的主要區別在於ConcurrentHashMap將僅鎖定正在更新的數據部分,而其餘線程能夠訪問其餘部分數據。 可是, Collections.synchronizedMap()將在更新時鎖定全部數據,其餘線程僅在釋放鎖定後才能訪問數據。 若是更新操做不少而讀取操做相對較少,則應選擇ConcurrentHashMapspa

另一個區別是ConcurrentHashMap不會保留傳入的Map中元素的順序。它在存儲數據時相似於HashMap 。 不能保證保留元素順序。 雖然Collections.synchronizedMap()將保留在經過Map的元素順序。例如,若是你傳遞一個TreeMapConcurrentHashMap ,這些元素才能在ConcurrentHashMap可能不同,在順序TreeMap ,但Collections.synchronizedMap()將保留順序。 .net

此外, ConcurrentHashMap能夠保證在一個線程更新映射而另外一個線程遍歷從映射得到的迭代器時,不會引起ConcurrentModificationException 。 可是,對此不保證Collections.synchronizedMap()線程

一篇文章展現了這二者的區別以及ConcurrentSkipListMapcode


#5樓

併發哈希圖

  • 當項目中須要很高的併發時,應使用ConcurrentHashMap。
  • 它是線程安全的,無需同步整個映射。
  • 用鎖完成寫操做時,讀操做可能會很是快。
  • 在對象級別沒有鎖定。
  • 在哈希圖存儲桶級別,鎖定的粒度要精細得多。
  • 若是一個線程嘗試修改它,而另外一個線程對其進行迭代,則ConcurrentHashMap不會引起ConcurrentModificationException。
  • ConcurrentHashMap使用多個鎖。

SynchronizedHashMap

  • 對象級別的同步。
  • 每一個讀/寫操做都須要獲取鎖定。
  • 鎖定整個集合是性能開銷。
  • 本質上,這僅容許訪問整個地圖的一個線程,並阻止全部其餘線程。
  • 它可能引發爭用。
  • SynchronizedHashMap返回Iterator,併發修改後快速失敗。

資源

相關文章
相關標籤/搜索