2013-06-04 55 views
3

的我正在讀關於ConcurrentHashMap迭代的ConcurrentHashMap

我讀到它提供了一個迭代器,它不需要同步,甚至可以在迭代期間修改映射,因此不會有ConcurrentModificationException

我想知道這是否是件好事,因爲我可能不會在早些時候將它放入ConcurrentHashMap,因爲另一個線程可能會改變它。

是我的思維是否正確?如果是的話,那麼好還是壞?

+0

我覺得這是非常有效的問題,而不是正確回答。示例兩個線程在同一個API上具有自己的迭代器;正在運行併發集合;並且必須移除其中的一個元素並且應該通知客戶。如果其刪除不能立即反映在其他人身上,那麼客戶將收到兩份通知,要求單個刪除該收集。 –

回答

4

我想知道這是否是一件好事,因爲我可能沒有得到元素,在迭代期間放入ConcurrentHashMap,因爲另一個線程可能已經改變了它。

我不認爲這應該是一個問題 - 如果你使用的同步和線程執行迭代發生搶鎖定並執行相同的聲明是真實的之前,將插入值的線程循環。

如果你需要一些你的線程之間的協調,以確保一些行動發生後,(只有)之後另一個動作,那麼你還需要管理這種協調,無論使用地圖的類型。

1

通常,ConcurrentHashMap弱一致的迭代器就足夠了。相反,如果你想有一個強烈一致的迭代器,那麼你有兩個選擇:

  1. ctrie是一個哈希數組映射線索提供恆定的時間快照。有數據結構可用Java source code
  2. Clojure的有PersistentHashMap,您可以使用 - 這可以讓你遍歷數據的快照。
  3. 使用本地數據庫,例如HSQLDB來存儲數據而不是使用ConcurrentHashMap。使用key | timestamp的組合主鍵,當你「更新」一個值時,你會用當前時間戳存儲一個新條目。要獲取迭代器,請使用where timetamp < System.currentTimeMillis()子句檢索結果集,並遍歷結果集。

在這兩種情況下,你都迭代快照,所以你有一個強烈的一致的迭代器;在前一種情況下,存在內存耗盡的風險,而後一種情況則是更復雜的解決方案。

+0

我們正在處理Java,所以請不要使用其他編程語言,比如Clojure – Anand

+1

@Anand Clojure是用Java編寫的 - 你可以使用Clojure中的Java數據結構 –

+0

oh ..是它?對不起,我不知道它..謝謝 – Anand

0

整點併發 - 事情是你承認併發活動,並不相信所有訪問都是序列化的。對於大多數集合,如果不爲其工作,就無法期望元素間的一致性。

如果您不關心查看最新數據,但希望獲得一致(但可能較舊)的數據視圖,請查看純功能結構,如Finger Trees