【问题标题】:Java 8 HashTable vs HashMap Collision HandlingJava 8 HashTable 与 HashMap 冲突处理
【发布时间】:2019-03-28 19:38:00
【问题描述】:

我想澄清一下 Java 8 中 hashtable 和 hashmap 之间的区别。

据我所知,HashTable 的功能类似于 HashMap,但它是线程安全的,并且不允许空键或空值。我知道 Java 8 更新了 HashMap 类,因此当发生冲突时,它不会在存储桶中创建具有相同哈希码的项目的链接列表,而是创建一棵树。

hashtable也是这样吗?即使在碰撞之前,树也是默认存储方法吗? (例如,当第一个放入桶中的项目放在那里时,它只是一个没有分支的树根。)

另外,java 如何确保哈希表是线程安全的?当两个线程尝试同时访问一条数据时,它会创建一个队列吗?

【问题讨论】:

标签: java multithreading java-8 hashmap hashtable


【解决方案1】:

hashtable也是这样吗?

没有。

即使在碰撞之前,树也是默认存储方法吗? (例如,当第一个放入桶中的项目放在那里时,它只是一个没有分支的树根。)

没有。 HashMap 类有一个名为 TREEIFY_THRESHOLD 的常量(值 8)。

Javadoc 说 “使用树而不是列表的 bin 计数阈值。将元素添加到至少具有这么多节点的 bin 时,bin 会转换为树”。 p>

另外,java如何确保哈希表是线程安全的?

Hashtable 的 javadoc 明确表示:“与新的集合实现不同,Hashtable 是同步的

当两个线程同时访问一个数据时,是否会创建队列?

没有。

【讨论】:

    【解决方案2】:

    这个答案将非常具体到 JDK 中的当前实现,所以请记住这一点。

    1. 我知道 Java 8 更新了 HashMap 类,因此当发生冲突时,它不会在存储桶中创建具有相同哈希码的项目的链接列表,而是创建一棵树。

      hashtable也是这样吗?

    没有。 Hashtable 永远只是一个链表表。 Java 开发人员没有为此用例更新 Hashtable。这也应该更清楚地表明您可能无论如何都不应该使用 Hashtable。

    1. 即使在碰撞之前,树也是默认存储方法吗?

    这也是在 Java 8 中,直到今天,但是,不,这不是默认行为。一旦桶条目命中 8 个链接元素,HashMap 就会将该链接列表转换为二叉树。

    1. 另外,java 如何确保哈希表是线程安全的?当两个线程同时访问一条数据时,是否会创建队列?

    通过使每个方法同步,这意味着每个线程将在该方法上排队,而另一个线程当前正在访问 Hashtable 的任何方法。如果您想做原子放置或原子计算之类的事情,这会导致很多问题。

    如果您想要一个线程安全的映射 HashMap,请始终使用 ConcurrentHashMap,不要使用 Hashtable。

    【讨论】:

    • 次要内容:对于大多数人来说,“排队”意味着排队并获得先到先得的服务,但那是not the case for synchronized,所以使用“排队”这个词" 具有误导性。
    • 这是一个合理的观点,但我使用队列的方式与AbstractQueueSynchronizer 相同,它支持公平和不公平的锁获取。
    • 如果不是先到先得,那么监视器如何确定哪些线程得到优先级?
    • 他们没有。这就是synchronized 关键字强加给您的不公平锁获取问题的一部分。如果您希望强制执行公平有序获取,您可能需要使用new ReentrantLock(true),其中true 将锁定定义为“公平”。
    • 需要注意的是,不公平的锁获取通常比公平的表现更好。因此,您需要公平锁应该有技术原因。
    【解决方案3】:

    来自Hashtable的Java Docs

    在“哈希冲突”的情况下,单个存储桶存储多个 条目,必须按顺序搜索

    所以第一个问题的答案是“否”。它不会创建任何树。

    对于线程安全机制,Hashtable 在每个读\写方法上使用简单的同步。如果你关心性能和线程安全,你最好看看ConcurrentHashMap

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-12-04
      • 2012-12-23
      • 1970-01-01
      • 2014-08-10
      • 1970-01-01
      • 1970-01-01
      • 2018-07-21
      • 1970-01-01
      相关资源
      最近更新 更多