迭代器并发修改异常
如果在 doSomething() 中修改列表,此代码将抛出并发修改异常。是否可以通过将代码包含在某个同步块中来避免它?
List l = Collections.synchronizedList(new ArrayList());
// normal iteration -- can throw ConcurrentModificationException
// may require external synchronization
for (Iterator i=list.iterator(); i.hasNext(); ) {
doSomething(i.next());
}
This code will throw Concurrent Modification Exception if the list is modified in doSomething(). Is it possible to avoid it by enclosing the code in some synchronized block?
List l = Collections.synchronizedList(new ArrayList());
// normal iteration -- can throw ConcurrentModificationException
// may require external synchronization
for (Iterator i=list.iterator(); i.hasNext(); ) {
doSomething(i.next());
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
如果要从列表中删除项目,可以通过调用
iterator.remove()
而不是list.remove(iterator.next())
如果您要添加一个项目 - 好吧,创建迭代列表的副本并将其添加到那里
如果上面的代码片段是同一方法的一部分,那么您不需要同步列表或同步块 - 没有其他线程可以访问本地列表。
if you are removing an item from the list, you can do it by calling
iterator.remove()
instead oflist.remove(iterator.next())
if you are adding an item - well, create a copy of the iterated list and add it there
if the code snippet above is part of the same method, then you don't need a synchronized list or synchronized blocks - no other thread can access the local list.
您可以修改<如果您通过
迭代器
接口。您可以使用迭代器。 remove()
删除元素。You can modify a
Collection
while iterating over it if you do so through theIterator
interface. You can useIterator.remove()
to remove elements.当你迭代它的时候你不能修改它。同步在这里没有帮助。
编辑:我忘记迭代器确实有
remove
方法。所以是可以去除的。You cannot modify it while you are iterating over it. Synchronizing won't help here.
EDIT : I forgot iterator does have the
remove
method. So it is possible to remove.我同意其他人关于
Iterator
和remove()
的观点。关于同步,我想补充一点,同步旨在控制不同线程之间的交互。
一个对象通常有多个同步方法,并且一个方法会调用另一个方法。因此,语言设计者决定,同一个线程不会在同步上被自己阻塞。
另外,想想看,如果一个线程被阻塞等待自己,你就有了一个宏伟的饥饿视角! ;-)
所以这回答了您的问题之一:不可能通过同步代码来避免问题。
I agree with others about
Iterator
andremove()
.About synchronization, I wanted to add that synchronization is designed to control interactions between different threads.
It is typical for an object to have several methods synchronized, and that one would call another. So the language designers decided that the same thread would not be blocked by himself on a synchronized.
Also, thinking about it, it a thread is blocked waiting for himself, you have a magnificent starvation perspective! ;-)
So this answers one of your questions: it is not possible to avoid the problem by synchronizing your code.
使用 CopyOnWriteArrayList 代替同步数组列表
Use
CopyOnWriteArrayList
instead of synchronized Array List