2012-12-17 69 views
2

據我所知,有兩種方法可以避免ConcurrentModificationException,而一個線程迭代集合,另一個線程修改集合。避免迭代器的方法ConcurrentModificationException

  1. 客戶端鎖定,基本上在迭代期間鎖定集合。需要訪問集合的其他線程將會阻塞,直到迭代完成。
  2. 「線程限制」克隆集合並迭代副本。

我想知道有沒有其他的選擇? ,因爲第一種方法顯然是不可取的,性能差,如果集合很大,其他線程可能會等待很長時間。第二種方式我不知道,因爲我們克隆了集合,並且迭代了副本,所以如果其他線程進來並修改原始副本,那麼複製的副本就變得陳舊了?這是否意味着我們需要通過克隆重新啓動並在修改後重新進行迭代?

+0

還有第三種方法也可以使用['CopyOnWriteArrayList'(http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/CopyOnWriteArrayList.html)如果你是寫入少於讀取。 –

+0

@AmitD你能否解釋更多關於它的原因?爲什麼寫入少於讀取?它是否像concurrentHashMap一樣工作? – peter

回答

7

我想知道是否有其他的選擇嗎?

使用不引發此異常的併發集合之一。相反,它們提供的一致性較弱即迭代時添加或刪除元素可能會或可能不會出現。

http://docs.oracle.com/javase/tutorial/essential/concurrency/collections.html

java.util.concurrent包包括多個補充Java集合框架的。這些是最容易通過提供的蒐集接口分類:

  • 的BlockingQueue定義了一個先入先出的數據結構,當您嘗試添加到隊列滿,或檢索從空隊列塊或超時。
  • ConcurrentMap是定義有用的原子操作的java.util.Map的子接口。這些操作僅在鍵存在時才刪除或替換鍵值對,或者僅在鍵不存在時才添加鍵值對。使這些操作原子化有助於避免同步。 ConcurrentMap的標準通用實現是ConcurrentHashMap,它是HashMap的併發模擬。
  • ConcurrentNavigableMap是支持近似匹配的ConcurrentMap的子接口。 ConcurrentNavigableMap的標準通用實現是ConcurrentSkipListMap,它是TreeMap的併發模擬。
+0

我想知道哪一個是最廣泛的,更喜歡在實踐中使用?在上述2個併發包集合中? – peter

+0

@ user1389813適合您需求的產品就是您要使用的產品。它們不可互換。在你的原因中,你可能想要CopyOnWriteArraList,CopyOnWriteArraySet,ConcurrentLinkedDeque或其他許多併發集合之一。 –

+0

你說過「添加或刪除的元素可能會或可能不會在迭代時出現」,那麼我們如何知道它是否出現? – peter

相關問題