Java同步列表

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (47)

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

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

void remove(String item)
{
     do something; (doesn't work on the list)
     list.remove(item);
}
提问于
用户回答回答于

是的,如果您也在迭代列表,请小心,因为在这种情况下,您需要同步它。从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哪个写入较慢但不存在此问题。

用户回答回答于

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

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

另外,请确保在迭代时同步列表中的内容:

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

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

扫码关注云+社区