ConcurrentHashMap和Hashtable在Java中有什么区别?
对于多线程应用程序,哪一个更有效率?
Hashtable
属于Collection框架; ConcurrentHashMap
属于Executor框架。Hashtable
使用一个单一锁来锁定整个数据。而ConcurrentHashMap
在段(默认为16)级别上使用多个锁,而不是对象级别,即整个Map
。ConcurrentHashMap
仅针对更新应用锁定。在检索的情况下,它允许完全并发性,检索反映最近完成的更新操作的结果。因此读取可以非常快,而写入则需要锁定。ConcurrentHashMap
如果一个线程尝试在另一个线程对其进行迭代时修改它,不会抛出ConcurrentModificationException
,也不允许空值。ConcurrentHashMap
返回Iterator
,具有故障安全性(即迭代器将复制内部数据结构),以避免并发修改。ConcurrentHashMap
使用数据库分片逻辑(Segment<K,V> [] segments
)称为并发级别,即将数据划分为分片(段),然后在每个分片(段)上放置锁,而不是为整个数据(Map
)放置单个锁。默认值为16。要更深入地了解ConcurrentHashMap,请参阅此链接 link
以下比喻仅用于理解概念(而不是逻辑)
Hashtable
和ConcurrentHashMap
是两种类型的住宅。Hashtable
锁定家庭的主门。ConcurrentHashMap
锁定特定房间门而不是主门。对于多线程应用程序来说,ConcurrentHashMap
更加高效。
ConcurrentHashMap
使用多个桶来存储数据。这样可以避免读取锁并且大大提高了性能,而 HashTable
则没有这种优化。两者都是线程安全的,但使用 ConcurrentHashMap
可以获得明显的性能优势。
当使用 get()
从 ConcurrentHashMap
中读取时,不存在锁定问题,与之相反,HashTable
的所有操作都被简单地同步处理。
HashTable
已经发布于早期版本的 Java 中,而 ConcurrentHashMap
是 Java 5+ 版本中推出的。
HashMap
在单线程应用程序中是最好的选择。
ConcurrentHashMap.putIfAbsent()
,在旧的Hashtable
中没有相应的方法。当你只从ConcurrentHashMap
中读取数据时,不会有锁,而对于Hashtable
,所有操作都是同步的。 - Frank Pavageau
HashMap
。 - Keith Randall