2012-12-13 59 views
1

假設在我的類中有兩個方法,分別是writeToMap()processKey(),並且這兩個方法都由多個線程調用。 writeToMap是一種在hashmap中寫入內容的方法,processKey()用於基於HashMapkeySet執行某些操作。Java中的ConcurentModificationException HashMap

在processKey中,我首先複製了originalMap,然後纔得到密鑰集。

new HashMap<String, Map<String,String>(originalMap).get("xx").keySet(); 

但我仍然得到ConcurrentModificationException即使我總是複製hashmap。有什麼問題?

回答

3

HashMap的複製構造函數在被複制的地圖(originalMap)上執行(隱藏)iteration。如果在迭代過程中originalMap被另一個線程修改,您可能會收到一個ConcurrentModificationException異常。

+0

那麼有什麼解決方案? – Bear

+1

最直接的解決方案是對原始地圖使用線程安全的地圖。例如,您可以使用ConcurrentHashMap。那麼你不需要創建一個副本。另外請注意,由於值本身就是映射,因此如果它們被同時訪問和修改,它們也需要線程安全。 – sjlee

+0

我在想,是ConcurrentHashMap真的解決了這個問題。從我的unsentanding,ConcurrentHashMap只是確保get和put是原子的。 – Bear

2

您已經嵌套地圖,並且在從內部地圖獲取內部地圖之前複製外部地圖。請注意,內部映射尚未被複制,所以當您迭代它時,仍然使用共享數據結構。

很難說基於簡短的代碼片段,但我認爲你不需要複製外部地圖,而且你確實需要複製內部地圖。