Java 8 HashTable 与 HashMap 的冲突处理

Java 8 HashTable vs HashMap Collision Handling

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

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

哈希表也是这样吗?树是碰撞前的默认存储方法吗? (例如,当第一个适合桶的物品放在那里时,它只是一个没有树枝的树根。)

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

来自哈希表的 Java Docs

In the case of a "hash collision", a single bucket stores multiple entries, which must be searched sequentially

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

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

此答案将非常具体地针对 JDK 中的当前实现,因此请记住这一点。

  1. I am aware that Java 8 updates the HashMap class so that when there's a collision, rather than create a linked list of items with the same hash code in the bucket, it creates a tree.

    Is this also the case with hashtable?

没有。 Hashtable 只会成为链表的 table。 Java 开发者没有为这个用例更新 Hashtable。这也应该更清楚地表明您可能无论如何都不应该使用 Hashtable 。

  1. And is the tree the default storage method even before a collision?

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

  1. Also, how does java ensure that a hashtable is threadsafe? Does it create a que when two threads try to concurrently access a piece of data?

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

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

Is this also the case with hashtable?

没有

And is the tree the default storage method even before a collision? (As in, when the first item to fit into a bucket is placed there, it's just a tree root with no branches.)

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

Javadoc 说 "The bin count threshold for using a tree rather than list for a bin. Bins are converted to trees when adding an element to a bin with at least this many nodes".

Also, how does java ensure that a hashtable is threadsafe?

Hashtable 的 javadoc 显式说:"Unlike the new collection implementations, Hashtable is synchronized".

Does it create a que when two threads try to concurrently access a piece of data?

没有