迭代多线程列表而不同步整个过程

时间:2014-08-29 20:12:20

标签: java multithreading list iterator synchronization

我有多线程代码和一个数组,所有线程都应该访问它,只有一个可以修改它(添加,删除,...)或修改其中的对象 我需要一种让线程访问它的安全方法。 我读到了锁互斥锁同步,同步列表,copyonwritearraylist和volatile。

会有很多迭代,所以我不能像这样在循环之外进行同步:

synchronized (list) {
    Iterator i = list.iterator();
    //Must be in synchronized block
    while (i.hasNext())
        foo(i.next());
}

因为我将失去多线程的优势而且我的列表大小可能达到1000左右所以我无法锁定整个列表而迭代所有这些项目

我还读过有关CopyOnWriteArrayList的内容,它适用于列表用于迭代不被修改的情况

那么对于像我这样的情况使用什么是最好的解决方案

1 个答案:

答案 0 :(得分:2)

CopyOnWriteArrayList实际上可能就是你想要的。它允许您迭代列表的快照,因为它存在于某个时间点。它可能与列表不同,因为现在,但你真的需要它吗?

以这种方式思考。迭代列表的线程和修改列表的线程可以以各种方式交错它们的操作,其中没有一个是错误的。一种可能性是迭代线程可以在修改线程被安排运行之前迭代整个列表。另一种可能性是迭代线程在修改之前将在列表的中途到达。将更改传播到所有现有迭代器将是一项复杂且昂贵的操作,并且您必须仔细定义迭代器的作用,例如,在其当前位置下方插入某些内容时。并且所有这些复杂性都不会使程序更正确,因为如果线程恰好以稍微不同的方式进行调度,则行为将与CopyOnWriteArrayList相同。

这是一种在高效,高度并发的程序中经常遇到的模式。重要的是一个线程正在一个对象的有效快照上运行,不一定是该对象的当前版本,因为它是其他一些线程所知道的。