簡體   English   中英

Java ConcurrentModificationException:是否可以在迭代時向哈希表添加元素?

[英]Java ConcurrentModificationException: Is it possible to add elements to a hashtable while iterating through it?

我正在迭代Hashtable並且在某一點上,我在Hashtable添加了一些東西,這顯然給了我一個ConcurrentModificationException 我理解為什么我會收到錯誤,但有沒有辦法解決這個問題,以至於我仍然可以遍歷Hashtable並同時添加值?

來自文檔

所有這個類的“集合視圖方法”返回的集合的迭代器方法返回的迭代器都是快速失敗的:如果在創建迭代器之后的任何時候對Hashtable進行結構修改,除非通過迭代器自己的刪除方法,迭代器將拋出ConcurrentModificationException。 因此,在並發修改的情況下,迭代器快速而干凈地失敗,而不是在未來的未確定時間冒着任意的,非確定性行為的風險。 Hashtable的鍵和元素方法返回的枚舉不是快速失敗的。

請注意,迭代器的快速失敗行為無法得到保證,因為一般來說,在存在不同步的並發修改時,不可能做出任何硬性保證。 失敗快速迭代器會盡最大努力拋出ConcurrentModificationException。 因此,編寫依賴於此異常的程序以確保其正確性是錯誤的:迭代器的快速失敗行為應該僅用於檢測錯誤。

如果您需要這種行為,您可以安全地復制該組密鑰並遍歷該副本。 如果散列表很大並且復制鍵集可能很昂貴的另一個選擇是在迭代期間添加到單獨的集合並添加單獨的集合迭代后的元素。

您可能還想了解CopyOnWriteSet,它專門為安全迭代而設計,同時修改了set。 請注意,迭代器只能看到原始集。 在下一次迭代之前,任何添加都不可見。

http://download.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/CopyOnWriteArraySet.html

這在許多讀者/少數作家場景中最有用。 如果在同一代碼路徑中進行讀寫,則不太可能是最有效的解決方案。

創建一個新的Hashtable,您可以添加新條目; 然后當你完成迭代時,添加第一個表中的條目。

(可選)如果需要,可以跳過原始表中存在的鍵。

另一種方法是使用ConcurrentHashMap而不是HashMap。 然而:

  • ConcurrentHashMap的迭代器被定義為在創建迭代器時或之后返回反映狀態的對象。 更精確的行為陳述在相關方法的javadoc中。

  • ConcurrentHashMap可能比常規HashMap慢。

暫無
暫無

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

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