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 中的当前实现,因此请记住这一点。
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 。
And is the tree the default storage method even before a collision?
同样,这在 Java 8 中,从今天开始,但是,不,这不是默认行为。一旦桶条目命中 8 个链接元素,HashMap 就会将该链接列表转换为二叉树。
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?
没有
我想澄清一下 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 中的当前实现,因此请记住这一点。
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 。
And is the tree the default storage method even before a collision?
同样,这在 Java 8 中,从今天开始,但是,不,这不是默认行为。一旦桶条目命中 8 个链接元素,HashMap 就会将该链接列表转换为二叉树。
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?
没有