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