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会产生额外的工作,为什么不使用a
java.util.Vector
而是?使用这种方法有优势吗?
我在http://www.coderanch.com/上发现了这个问题,我在同一篇文章中分享了它的好答案。
答案 0 :(得分:7)
在java.util.Collections JavaDoc中,您可以读到“当迭代时,用户必须手动同步返回的列表:”
如果您在列表上执行多个事务(例如迭代它),则同步列表将无法保护您免受ConcurrentModificationException
的攻击。当你在迭代它时会有人在列表中添加或删除它,并且会抛出。
Collections.synchronizedList()
保护列表不受来自多个线程的并发操作的影响。在迭代器的情况下,您正在进行列表调用,然后返回到您的代码,然后再次进行列表调用。即使方法是同步的,在此期间也不会受到列表中其他线程运行的竞争条件的保护。
使用同步的ArrayList会产生额外的工作,为什么不使用java.util.Vector呢?使用这种方法有优势吗?
Vector
在这里没有帮助。它也会在同样的情况下抛出异常。引用javadocs:
Vector的iterator和listIterator方法返回的迭代器是快速失败的:如果在创建Iterator之后的任何时候对Vector进行结构修改,除了通过Iterator自己的remove或add方法之外,Iterator将抛出一个ConcurrentModificationException的。
此外,Vector
是一个非常古老的类。人们普遍认为最好使用同步ArrayList
。
以下是您可以做的几件事:
ConcurrentHashMap
(当然不是列表),在您进行迭代时处理对集合的修改。 ConcurrentSkipList
或LinkedBlockingQueue
是其他选择。