在迭代时是否有支持并发修改的列表集合?

时间:2013-12-22 15:08:01

标签: java list collections concurrency iteration

是否有一个实现List接口的容器在迭代时支持并发修改?具体来说,我希望一个线程迭代集合,而许多线程插入并从此列表中删除元素。迭代器应该看到它尚未遍历的列表的修改。

我正在寻找类似于ConcurrentLinkedQueue的迭代行为,但支持在特定索引处添加和删除元素。最好是我正在寻找强一致性(我愿意为它支付锁争用开销)但我可能生活在弱一致性。

我很高兴看到第三方库,因为我在标准库中看不到任何可以提供我正在寻找的东西。

2 个答案:

答案 0 :(得分:5)

有一些接近的东西。它被称为CopyOnWriteArrayList - 尽管有一个限制,即迭代器在迭代时不会看到所做的更改,而是继续迭代迭代开始时的集合。

该集合在写入时速度很慢(但读取速度很快),这是另一回事。

jME3有一个名为SafeArrayList doc here的内部集合,它更快但不支持多线程访问。它确实支持从迭代器等访问(因此你可以循环遍历列表中的对象并同时添加/删除它们,只要你不尝试从多个线程执行此操作)。同样,迭代器在迭代时不会看到所做的更改,它们将继续迭代原始数据。

并发包提供了许多其他可能有用的数据结构。

另一种方法是在列表中使用标准ArrayListsynchronize进行修改和读取,然后使用索引对其进行迭代。 (即list.get(i))。

但是会有很多边缘情况。例如,如果你删除一个元素,它会将所有其他元素向下移动,这样你就可以跳过那个点之后的任何迭代器。

实际上,您最终可能需要保留迭代器列表,并在添加/删除元素时循环遍历迭代器列表并相应地更新其位置!

答案 1 :(得分:0)

单独使用Java API,您可以使用Collections.synchronizedList()获取同步列表。检查方法的规格是否符合您的使用要求。并且,使用ListIterator(使用List.listIterator()方法获得)来迭代和修改列表。