gpt4 book ai didi

java - 为什么在syncedList()或Vector已经同步的情况下,为什么我们仍然需要外部同步?

转载 作者:行者123 更新时间:2023-12-03 20:30:44 25 4
gpt4 key购买 nike

ArrayList不同步。但是有一种方法可以获取同步,如java.util.ArrayList的JavaDoc中所述:

List list = Collections.synchronizedList(new ArrayList(...));

java.util.Collections JavaDoc中,您可以看到“ ,当用户在返回列表上进行迭代时,必须手动对其进行同步:
synchronized(list) {
Iterator i = list.iterator(); // Must be in synchronized block
while (i.hasNext())
foo(i.next());
}

使用同步的ArrayList会导致其他工作,为什么不使用
改为 java.util.Vector?使用这种方法是否有优势?

我在 http://www.coderanch.com/上发现了这个问题,我在同一篇文章中分享了这个很好的答案。

最佳答案

In java.util.Collections JavaDoc you can read that "It is imperative that the user manually synchronize on the returned list when iterating over it:"



如果您要在一个列表上进行多个事务(例如遍历整个列表),那么同步列表将无法保护您免受 ConcurrentModificationException的侵害。在您遍历列表时,仍然有可能有人在列表中添加或删除该列表,这将引发该错误。
Collections.synchronizedList()保护列表免受来自多个线程的并发操作的影响。对于迭代器,您正在进行列表调用,但随后返回到代码,然后再次进行列表调用。即使方法已同步,但同时也无法防止其他线程在列表上运行的竞争条件。

Using a synchronized ArrayList results in additional work, why not use a java.util.Vector instead? Is there an advantage in using this approach?


Vector在这里无济于事。在相同情况下,它也会引发异常。引用javadocs:

The Iterators returned by Vector's iterator and listIterator methods are fail-fast: if the Vector is structurally modified at any time after the Iterator is created, in any way except through the Iterator's own remove or add methods, the Iterator will throw a ConcurrentModificationException.



另外, Vector是一个非常老的类。人们普遍认为,最好使用同步的 ArrayList

您可以执行以下几项操作:
  • 您可以将列表复制到另一个集合中,然后可以对其进行迭代。即使其他线程在同步列表中添加或删除,本地集合也是安全的。当然,这不能保护您免受对列表元素的修改。
  • 您可以切换到完全并发的集合,例如ConcurrentHashMap(当然不是列表),它可以在迭代时处理对该集合的修改。 ConcurrentSkipListLinkedBlockingQueue是其他选择。
  • 正如@Geek所指​​出的,CopyOnWriteArrayList是另一种选择,尽管性能在很大程度上取决于迭代和写入的比率。
  • 关于java - 为什么在syncedList()或Vector已经同步的情况下,为什么我们仍然需要外部同步?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20691757/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com