是否有一個容器實現List接口,在迭代時支持併發修改?具體來說,我希望一個線程迭代集合,而許多線程插入和從列表中刪除元素。迭代器應該看到它尚未遍歷的列表的修改。有迭代時支持併發修改的列表集合嗎?
我在尋找類似的ConcurrentLinkedQueue但添加和刪除特定索引元素的支持迭代行爲。最好我在尋找強大的一致性(並且願意爲它爭取鎖定爭用開銷),但我可能生活在一致性較弱的環境中。
我很高興地看着第三方庫,因爲我看不到它提供什麼,我尋找的標準庫的東西。
是否有一個容器實現List接口,在迭代時支持併發修改?具體來說,我希望一個線程迭代集合,而許多線程插入和從列表中刪除元素。迭代器應該看到它尚未遍歷的列表的修改。有迭代時支持併發修改的列表集合嗎?
我在尋找類似的ConcurrentLinkedQueue但添加和刪除特定索引元素的支持迭代行爲。最好我在尋找強大的一致性(並且願意爲它爭取鎖定爭用開銷),但我可能生活在一致性較弱的環境中。
我很高興地看着第三方庫,因爲我看不到它提供什麼,我尋找的標準庫的東西。
有一些接近。它被稱爲CopyOnWriteArrayList
- 雖然限制是迭代器在迭代過程中不會看到所做的更改,但它會繼續迭代迭代開始時的迭代。
該集合是在寫入速度慢(但快上讀取),這是另一個要考慮的。
jME3有一個名爲SafeArrayList
doc here的內部集合,速度更快但不支持多線程訪問。它確實支持從迭代器等訪問tho(所以你可以循環遍歷列表中的對象,並且可以同時添加/刪除它們,只要不嘗試從多個線程執行)。迭代器在迭代時不會看到所做的更改,它們將繼續遍歷原始數據。
併發包提供了許多其他數據結構,其可以幫助爲好。
另一種方法是隻使用一個標準ArrayList
,synchronize
名單進行修改並閱讀,然後使用指數迭代它。 (即list.get(i)
)。
雖然會有很多邊緣案例。例如,如果你刪除一個元素,它會將所有其他元素全部洗掉,這樣你就可以跳過那個點上的迭代器。
事實上你可能最終需要不斷迭代器的列表,並通過你的迭代器的列表,當你添加/刪除元素循環,並相應地更新自己的位置!
單獨使用Java API,你可以使用Collections.synchronizedList()
獲得同步列表。檢查該方法的規格是否適合您的使用。然後使用ListIterator
(使用List.listIterator()
方法獲得)來迭代和修改列表。
這不起作用,它會在迭代時鎖定修改列表。 –
但鎖定集合寫入應該仍然很好,不是嗎? – Neel
他想要一個迭代器,它可以在迭代過程中看到所做的更改。如果收藏被鎖定,他們無法進行更改... –
道歉,我不知道這是脫離主題。我不是打算徵求意見,而是發現是否存在符合我需要的事情。 –