2

假設我有一個從客戶端發送到服務器的請求ID的散列集。服務器的響應返回我發送的請求ID,然後我可以從哈希集中刪除。這將以多線程的方式運行,因此多個線程可以添加和刪除哈希集中的ID。但是,由於生成的ID是唯一的(來自線程安全源,因此我們假設現在每個新請求都會更新一個AtomicInteger),那麼HashSet需要是ConcurrentHashSet如果線程使用不同的密鑰,是否需要ConcurrentHashSet?

我認爲這可能會導致問題的唯一情況是,如果HashSet遇到衝突可能需要數據結構更改爲基礎HashSet對象,但它似乎不會在此用例中發生。

+0

HashSet實現需要支持併發(如'ConcurrentHashSet')或者由'Collections.synchronizedSet'封裝。 –

回答

3

是的。由於散列表的底層數組可能需要調整大小,因爲當然ID可能會發生衝突。所以擁有不同的鑰匙根本無濟於事。

但是,由於您知道ID正在增加,並且您可以對未完成ID的最大數量(可以說是1000)有一個上限。您可以使用上限和下限以及固定大小的數組以及來自最低鍵的偏移索引,在這種情況下,您不需要任何互斥鎖或併發數據結構。這樣的數據結構非常脆弱,但是如果你的數據結構超過了你的上限,那麼地獄將會崩潰。所以除非關注性能,否則請使用ConcurrentHashSet

+0

但我不確定這些鍵是否會碰到類似獨特整數的東西。如果它是一個字符串,並且字符串散列相撞,我會同意。但我無法看到它發生的整數,特別是如果HashSet被預先設定。我認爲如果初始尺寸和載荷係數設置得當,如果您已經知道相對較小範圍(0-(2^30-1))範圍內的唯一值範圍,則不會發生碰撞。我正在考慮表現是一個問題,這就是爲什麼我正在探索這個問題。 – Marcus

+0

我不明白這些是否是字符串上的整數或散列關於碰撞的可能性有什麼區別。一個好的散列表應該以任何方式傳播輸入數據,但最終會出現衝突,並且您很可能忽略它們。 –

+0

'hashCode()'產生一個整數。假設我爲我的'HashSet '創建了一個'MyInteger'類,其中'MyInteger'具有與整數值相同的哈希碼。然後根據定義,不會有散列衝突。我不能輕易地爲任意長度的字符串做同樣的事情,因爲這將保證最終會發生衝突,但是'MyInteger'類保證不會。 – Marcus

相關問題