[英]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中的當前實現,因此請記住這一點。
我知道Java 8更新了HashMap類,以便在發生沖突時,而不是創建存儲桶中具有相同哈希碼的項目的鏈表,而是創建樹。
哈希表也是如此嗎?
不會。哈希表永遠只會是鏈接列表的表。 Java開發人員沒有為此用例更新Hashtable。 這也應該使您更清楚地知道您可能不應該使用Hashtable。
甚至在發生碰撞之前,樹是默認的存儲方法嗎?
再次重申,這是Java 8,直到今天,但是,這不是默認行為。 一旦存儲桶條目達到8個鏈接元素 ,HashMap就會將該鏈接列表轉換為二叉樹。
另外,java如何確保哈希表是線程安全的? 當兩個線程嘗試並發訪問數據時,是否會創建隊列?
通過使每個方法同步(即,每個線程將在該方法上排隊),而另一個線程當前正在訪問Hashtable的任何方法。 如果您要執行原子投放或原子計算之類的操作,則會導致很多問題。
如果您想要線程安全的映射HashMap,請始終使用ConcurrentHashMap,而不要使用Hashtable。
從Hashtable的Java文檔 :
如果發生“哈希沖突”,則單個存儲桶會存儲多個條目,這些條目必須按順序搜索
因此,第一個問題的答案是“否”。 它不會創建任何樹。
關於線程安全機制,Hashtable在每個讀寫方法上使用簡單的同步。 如果您擔心性能和線程安全性,最好查看ConcurrentHashMap 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.