迭代器并发修改异常

发布于 2024-08-21 15:40:39 字数 332 浏览 7 评论 0原文

如果在 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

趴在窗边数星星i 2024-08-28 15:40:39
  • 如果要从列表中删除项目,可以通过调用 iterator.remove() 而不是 list.remove(iterator.next())

  • 如果您要添加一个项目 - 好吧,创建迭代列表的副本并将其添加到那里

  • 如果上面的代码片段是同一方法的一部分,那么您不需要同步列表或同步块 - 没有其他线程可以访问本地列表。

  • if you are removing an item from the list, you can do it by calling iterator.remove() instead of list.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.

不喜欢何必死缠烂打 2024-08-28 15:40:39

可以修改<如果您通过 迭代器接口。您可以使用 迭代器。 remove() 删除元素。

You can modify a Collection while iterating over it if you do so through the Iterator interface. You can use Iterator.remove() to remove elements.

祁梦 2024-08-28 15:40:39

当你迭代它的时候你不能修改它。同步在这里没有帮助。

编辑:我忘记迭代器确实有 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.

夏花。依旧 2024-08-28 15:40:39

我同意其他人关于 Iteratorremove() 的观点。


关于同步,我想补充一点,同步旨在控制不同线程之间的交互。

一个对象通常有多个同步方法,并且一个方法会调用另一个方法。因此,语言设计者决定,同一个线程不会在同步上被自己阻塞。

另外,想想看,如果一个线程被阻塞等待自己,你就有了一个宏伟的饥饿视角! ;-)

所以这回答了您的问题之一:不可能通过同步代码来避免问题。

I agree with others about Iterator and remove().


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.

半暖夏伤 2024-08-28 15:40:39

使用 CopyOnWriteArrayList 代替同步数组列表

Use CopyOnWriteArrayList instead of synchronized Array List

空袭的梦i 2024-08-28 15:40:39
List l = Collections.synchronizedList(new ArrayList());

synchronized(l) { 
   // normal iteration -- can throw ConcurrentModificationException
   // may require external synchronization
   for (Iterator i=list.iterator(); i.hasNext(); ) {
      doSomething(i.next());
   }
}
List l = Collections.synchronizedList(new ArrayList());

synchronized(l) { 
   // normal iteration -- can throw ConcurrentModificationException
   // may require external synchronization
   for (Iterator i=list.iterator(); i.hasNext(); ) {
      doSomething(i.next());
   }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文