2013-12-22 63 views
5

是否有一個容器實現List接口,在迭代時支持併發修改?具體來說,我希望一個線程迭代集合,而許多線程插入和從列表中刪除元素。迭代器應該看到它尚未遍歷的列表的修改。有迭代時支持併發修改的列表集合嗎?

我在尋找類似的ConcurrentLinkedQueue但添加和刪除特定索引元素的支持迭代行爲。最好我在尋找強大的一致性(並且願意爲它爭取鎖定爭用開銷),但我可能生活在一致性較弱的環境中。

我很高興地看着第三方庫,因爲我看不到它提供什麼,我尋找的標準庫的東西。

+0

道歉,我不知道這是脫離主題。我不是打算徵求意見,而是發現是否存在符合我需要的事情。 –

回答

5

有一些接近。它被稱爲CopyOnWriteArrayList - 雖然限制是迭代器在迭代過程中不會看到所做的更改,但它會繼續迭代迭代開始時的迭代。

該集合是在寫入速度慢(但快上讀取),這是另一個要考慮的。

jME3有一個名爲SafeArrayListdoc here的內部集合,速度更快但不支持多線程訪問。它確實支持從迭代器等訪問tho(所以你可以循環遍歷列表中的對象,並且可以同時添加/刪除它們,只要不嘗試從多個線程執行)。迭代器在迭代時不會看到所做的更改,它們將繼續遍歷原始數據。

併發包提供了許多其他數據結構,其可以幫助爲好。

另一種方法是隻使用一個標準ArrayListsynchronize名單進行修改並閱讀,然後使用指數迭代它。 (即list.get(i))。

雖然會有很多邊緣案例。例如,如果你刪除一個元素,它會將所有其他元素全部洗掉,這樣你就可以跳過那個點上的迭代器。

事實上你可能最終需要不斷迭代器的列表,並通過你的迭代器的列表,當你添加/刪除元素循環,並相應地更新自己的位置!

0

單獨使用Java API,你可以使用Collections.synchronizedList()獲得同步列表。檢查該方法的規格是否適合您的使用。然後使用ListIterator(使用List.listIterator()方法獲得)來迭代和修改列表。

+0

這不起作用,它會在迭代時鎖定修改列表。 –

+0

但鎖定集合寫入應該仍然很好,不是嗎? – Neel

+0

他想要一個迭代器,它可以在迭代過程中看到所做的更改。如果收藏被鎖定,他們無法進行更改... –