当我的程序中的所有方法都同步时,是否有可能出现 ConcurrentModificationException?
即使我同步了整个程序的所有方法(包括静态方法和 main 方法),我还是收到了 ConcurrentModificationException 。
我没有隐藏的迭代器。
- 这怎么可能?
- 这是什么意思?
- 我该如何修复它?
I get a ConcurrentModificationException
even though I made all the methods of the whole program synchronized (including static methods and the main
method).
I don't have hidden iterators.
- How is that even possible?!
- What does it mean?
- How can I fix it?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
ConcurrentModificationException
可能是由同一个线程在迭代集合时操作集合引起的。ListIterator.add()
方法ConcurrentModificationException
can be caused by the same thread manipulating a collection while iterating over itIterator.remove()
orListIterator.add()
methodsConcurrentModificationException 与同步无关。
它与迭代集合时修改集合有关。正如 Lie Ryan 指出的那样,完整的堆栈跟踪将帮助我们指出你是如何得到它的。
通常,要解决此问题,您在迭代集合时不得修改集合本身。
ConcurrentModificationException is NOT related to synchronization.
It's related to modifying a collection while iterating through it. As Lie Ryan points out, a full stack trace would help us point out how you got it.
Generally, to fix this, you must not modify the collection itself while iterating through it.
如果你运行这个
你会得到一个commodification。如果不使用适当的函数,则无法在迭代集合时更改集合。
可以使用以下方法解决此问题:
If you run this
You will get a comodification. You cannot alter a collection while iterating over it without using the appropriate functions.
This can be resolved using the following:
好吧,首先,如果你看到了,这是可能的:如果鸟书和鸟不同意,就相信鸟。
现在,这怎么可能发生呢?如果没有看到您的代码,很难准确地说出,但异常堆栈跟踪将指向它发生的位置;你在周围看到了什么?
一般来说,显然,当您有并发访问时,就会发生这种情况。当您找到发生这种情况的位置时,问问自己哪些线程可能会到达那里。
Well, to start with, if you're seeing it, it's possible: if the bird book and the bird disagree, believe the bird.
Now, how can it happen? Hard to say exactly without seeing your code, but the exception stacktrace will point to the place it happened; what do you see around that?
In general, it's going to happen when you have, obviously, concurrent accesses. When you find the place in which it's happening, ask yourself what threads could be getting there.
当您迭代集合并在此期间从该集合中删除条目时,您会遇到此异常。
例如,
您必须将要删除的内容添加到另一个集合中,并在完成列表迭代后删除它们。
否则,您可以通过 iterator() 迭代对象集合,并在当前迭代器上调用 remove() 。
You get this exception when you're iterating over a collection and during this you remove an entry from this collection.
e.g.
You must add the ones you want to remove to another collection and remove them after your finished iterating over the list.
Otherwise, you iterate over the objects collection via it's iterator() and call remove() on the current iterator.
同步方法会在其运行的对象实例上放置一个锁。
如果对象 A 和 B 访问同一个集合,则 A#doStuff 和 B#doStuff 是否同步并不重要 - 它们仍然可以并发执行。
要锁定集合,您可能需要锁定集合本身:方法体中的synchronized(collection),或Java 5 互斥体(更好)。
(事实上,正如其他人指出的那样,即使在单个线程中也可能出现 ConcurrentModificationException )。
A synchronized method places a lock on the object instance it's running with.
If objects A and B access the same collection, it doesn't matter if A#doStuff and B#doStuff are synchronized - they can still execute concurrently.
To lock the collection, you probably want a lock on the collection itself: synchronized(collection) in the method bodies, or a Java 5 mutex (better).
(that and the fact that you can have ConcurrentModificationException even in a single thread as others have pointed out).
ConcurrentModificationException 的 javadoc 包含答案:
解决这个问题的方法就是不要这样做。
即,(正如其他人所指出的)如果您需要同时迭代和修改,请使用迭代器提供的方法,而不是直接修改集合。
The javadoc for ConcurrentModificationException contains the answer:
The way to fix it is to not do that.
I.e., (as others have noted) if you need to simultaneously iterate and modify, use the methods supplied by the iterator rather than modifying the collection directly.