Java中的ConcurrentHashMap和Hashtable

94

ConcurrentHashMap和Hashtable在Java中有什么区别?

对于多线程应用程序,哪一个更有效率?


2
对于非线程应用程序,请使用 HashMap - Keith Randall
建议使用ConcurrentHashMap而不是Hashtable。请查看此文章:http://www.ibm.com/developerworks/java/library/j-jtp07233/index.html - Subhrajyoti Majumder
另请参见https://dev59.com/E3VD5IYBdhLWcg3wQJOT#40878以获取更多信息。 - Pacerier
@Keith Randall,Java 中没有非线程化的应用程序。它要么是多线程的,要么是单线程的(仅主线程)。您正在谈论单线程应用程序。 - AzarEJ
2个回答

177
ConcurrentHashMap和Hashtable的锁定机制
  • Hashtable属于Collection框架; ConcurrentHashMap属于Executor框架。
  • Hashtable使用一个单一锁来锁定整个数据。而ConcurrentHashMap在段(默认为16)级别上使用多个锁,而不是对象级别,即整个Map
  • ConcurrentHashMap仅针对更新应用锁定。在检索的情况下,它允许完全并发性,检索反映最近完成的更新操作的结果。因此读取可以非常快,而写入则需要锁定。
  • ConcurrentHashMap如果一个线程尝试在另一个线程对其进行迭代时修改它,不会抛出ConcurrentModificationException,也不允许空值。
  • ConcurrentHashMap返回Iterator,具有故障安全性(即迭代器将复制内部数据结构),以避免并发修改。
  • ConcurrentHashMap使用数据库分片逻辑(Segment<K,V> [] segments )称为并发级别,即将数据划分为分片(段),然后在每个分片(段)上放置锁,而不是为整个数据(Map)放置单个锁。默认值为16。

要更深入地了解ConcurrentHashMap,请参阅此链接 link

以下比喻仅用于理解概念(而不是逻辑)

  • 假设HashtableConcurrentHashMap是两种类型的住宅。
  • Hashtable锁定家庭的主门。
  • ConcurrentHashMap锁定特定房间门而不是主门。

对于多线程应用程序来说,ConcurrentHashMap 更加高效。


53
样例战胜了所有理论 :) - Mehraj Malik
1
这是否意味着ConcurrentHashMap比HashTable更好?在什么情况下,HashTable比另一个更好? - Tiina
@Tiina,Hashtable从来都不是首选的类。如果你的程序需要线程安全,使用ConcurrentHashMap。如果不需要,使用java.util.HashMap。 - undefined

126

ConcurrentHashMap 使用多个桶来存储数据。这样可以避免读取锁并且大大提高了性能,而 HashTable 则没有这种优化。两者都是线程安全的,但使用 ConcurrentHashMap 可以获得明显的性能优势。

当使用 get()ConcurrentHashMap 中读取时,不存在锁定问题,与之相反,HashTable 的所有操作都被简单地同步处理。 HashTable 已经发布于早期版本的 Java 中,而 ConcurrentHashMap 是 Java 5+ 版本中推出的。

HashMap 在单线程应用程序中是最好的选择。


15
还有一个ConcurrentHashMap.putIfAbsent(),在旧的Hashtable中没有相应的方法。当你只从ConcurrentHashMap中读取数据时,不会有锁,而对于Hashtable,所有操作都是同步的。 - Frank Pavageau
2
@FrankPavageau在原始答案中添加了非常有用的评论。 - Algorithmist

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接