ConcurrentHashMap和Collections.synchronizedMap(Map)的區別是什么?
我有一個會被多個線程同時修改的Map
在Java的API里面,有3種不同的實現了同步的Map實現
- Hashtable
- Collections.synchronizedMap(Map)
- ConcurrentHashMap
據我所知,HashTable 已經是一個很老的實現了(擴展了已經過時的字典類)。后來為了適配Map接口進行了調整,它存在著嚴重的伸縮性問題,已經不鼓勵在新項目里面使用了
但是關于其他的兩個呢?ConcurrentHashMap和Collections.synchronizedMap(Map)的區別是什么?分別適合什么場景呢?
回答一
╔═══════════════╦═══════════════════╦═══════════════════╦═════════════════════╗
║ Property ║ HashMap ║ Hashtable ║ ConcurrentHashMap ║
╠═══════════════╬═══════════════════╬═══════════════════╩═════════════════════╣
║ Null ║ allowed ║ not allowed ║
║ values/keys ║ ║ ║
╠═══════════════╬═══════════════════╬═════════════════════════════════════════╣
║ Thread-safety ║ ║ ║
║ features ║ no ║ yes ║
╠═══════════════╬═══════════════════╬═══════════════════╦═════════════════════╣
║ Lock ║ not ║ locks the whole ║ locks the portion ║
║ mechanism ║ applicable ║ map ║ ║
╠═══════════════╬═══════════════════╩═══════════════════╬═════════════════════╣
║ Iterator ║ fail-fast ║ weakly consistent ║
╚═══════════════╩═══════════════════════════════════════╩═════════════════════╝
關于鎖的機制,HashTable鎖一個對象, ConcurrentHashMap只鎖一個桶
回答二
按照你的需求,使用ConcurrentHashMap吧。它允許Map被多個線程并發修改并且是非阻塞的。 Collections.synchronizedMap(map) 創建的是一個阻塞的Map,會降低性能的,盡管可以保持一致性(使用正確的話)
用第二個選擇的話,你就需要保證數據的一致性,每一個線程都需要有一個map的最新的視圖。如果性能是至關重要的話,那就用第一種,每個線程只能插入數據到map,并且讀取的頻率會更低。
回答三
ConcurrentHashMap是更好的,如果你可以使用到的話,因為它至少需要Java5版本
它設計的初衷就是多線程情況下的高伸縮性。當只有一個線程使用的話,性能不會太好的,但是多線程使用這個map的時候就好得多了。
我找到一個博客復制了一個表格,來自一本我很推薦的名叫Java Concurrency In Practice的優秀書籍
Collections.synchronizedMap只有在你需要用其他特性去包裝一個map的時候,它才有意義,例如一些排序的map,像treemap那種。
文章翻譯自Stack Overflow:https://stackoverflow.com/questions/510632/whats-the-difference-between-concurrenthashmap-and-collections-synchronizedmap