簡體   English   中英

Java 8 HashTable與HashMap沖突處理

[英]Java 8 HashTable vs HashMap Collision Handling

我想澄清一下Java 8中的hashtable和hashmap之間的區別。

據我所知,HashTable的功能類似於HashMap,但具有線程安全性,並且不允許空鍵或空值。 我知道Java 8更新了HashMap類,以便在發生沖突時,而不是創建存儲桶中具有相同哈希碼的項目的鏈表,而是創建樹。

哈希表也是如此嗎? 甚至在發生碰撞之前,樹是默認的存儲方法嗎? (例如,將第一個可放入桶中的物品放在那里時,它只是沒有分支的樹根。)

另外,java如何確保哈希表是線程安全的? 當兩個線程嘗試並發訪問數據時,是否會創建隊列?

哈希表也是如此嗎?

沒有。

甚至在發生碰撞之前,樹是默認的存儲方法嗎? (例如,將第一個可放入桶中的物品放在那里時,它只是沒有分支的樹根。)

號的HashMap類有一個名為恆定TREEIFY_THRESHOLD (值8)。

Javadoc說: “使用樹而不是容器列表的容器計數閾值。將元素添加到具有至少這么多節點的容器中時,容器將轉換為樹”

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

Hashtable的javadoc明確表示: “與新的集合實現不同,Hashtable是同步的

當兩個線程嘗試並發訪問數據時,是否會創建隊列?

沒有。

這個答案將非常特定於JDK中的當前實現,因此請記住這一點。

  1. 我知道Java 8更新了HashMap類,以便在發生沖突時,而不是創建存儲桶中具有相同哈希碼的項目的鏈表,而是創建樹。

    哈希表也是如此嗎?

不會。哈希表永遠只會是鏈接列表的表。 Java開發人員沒有為此用例更新Hashtable。 這也應該使您更清楚地知道您可能不應該使用Hashtable。

  1. 甚至在發生碰撞之前,樹是默認的存儲方法嗎?

再次重申,這是Java 8,直到今天,但是,這不是默認行為。 一旦存儲桶條目達到8個鏈接元素 ,HashMap就會將該鏈接列表轉換為二叉樹。

  1. 另外,java如何確保哈希表是線程安全的? 當兩個線程嘗試並發訪問數據時,是否會創建隊列?

通過使每個方法同步(即,每個線程將在該方法上排隊),而另一個線程當前正在訪問Hashtable的任何方法。 如果您要執行原子投放或原子計算之類的操作,則會導致很多問題。

如果您想要線程安全的映射HashMap,請始終使用ConcurrentHashMap,而不要使用Hashtable。

從Hashtable的Java文檔

如果發生“哈希沖突”,則單個存儲桶會存儲多個條目,這些條目必須按順序搜索

因此,第一個問題的答案是“否”。 它不會創建任何樹。

關於線程安全機制,Hashtable在每個讀寫方法上使用簡單的同步。 如果您擔心性能和線程安全性,最好查看ConcurrentHashMap

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM