Java 同步列表

2022-08-31 15:11:44

我有一个预填充的数组列表。我有多个线程,它们将从数组列表中删除元素。每个线程调用下面的 remove 方法,并从列表中删除一个项目。以下代码是否为我提供了一致的行为?

ArrayList<String> list = Collections.synchronizedList(new ArrayList<String>());

void remove(String item)
{
     do something; (doesn't work on the list)
     list.remove(item);
}

谢谢!


答案 1

是的,如果您还要迭代列表,请小心,因为在这种情况下,您需要对其进行同步。来自 Javadoc

用户在迭代返回的列表时必须手动同步该列表:

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

或者,您可以使用写入速度较慢但没有问题的方法。CopyOnWriteArrayList


答案 2

这应该没问题,只要你不要求“remove”方法是原子的。

换句话说,例如,如果“执行某些操作”检查该项目是否在列表中出现多次,则当您到达下一行时,该检查的结果可能会出错。

此外,请确保在迭代时在列表上进行同步:

synchronized(list) {
    for (Object o : list) {}
}

正如Peter Lawrey所提到的,CopyOnWriteArrayList可以使您的生活更轻松,并且可以在高度并发的环境中提供更好的性能。