修复ConcurrentModificationException问题
我有一个问题。同时访问 Vector 时出现 ConcurrentModificationException。我向所有向量迭代添加了同步块,但可能忘记了一个,或者存在另一个泄漏。
问题是错误堆栈跟踪显示的错误是对 Vector.retainAll() 的调用,这是一个同步方法。我如何猜测碰撞中涉及的另一点是什么?
提前致谢
08-24 13:37:25.968: ERROR/AndroidRuntime(6582): java.util.ConcurrentModificationException
08-24 13:37:25.968: ERROR/AndroidRuntime(6582): at java.util.AbstractList$SubAbstractList.listIterator(AbstractList.java:320)
08-24 13:37:25.968: ERROR/AndroidRuntime(6582): at java.util.AbstractList$SubAbstractList.iterator(AbstractList.java:307)
08-24 13:37:25.968: ERROR/AndroidRuntime(6582): at java.util.AbstractCollection.contains(AbstractCollection.java:128)
08-24 13:37:25.968: ERROR/AndroidRuntime(6582): at java.util.Collections$SynchronizedCollection.contains(Collections.java:432)
08-24 13:37:25.968: ERROR/AndroidRuntime(6582): at java.util.AbstractCollection.retainAll(AbstractCollection.java:319)
08-24 13:37:25.968: ERROR/AndroidRuntime(6582): at java.util.Vector.retainAll(Vector.java:856)
I have a problem. Accessing to a Vector concurrently I get an ConcurrentModificationException. I added synchronized blocks to all the vector iterations but maybe forgot one or there is another leak.
The problem is that the in error stacktrace the error shown is a call to Vector.retainAll() which is a synchronized method. How can I guess whats the other point involved in the collision?
Thanks in advance
08-24 13:37:25.968: ERROR/AndroidRuntime(6582): java.util.ConcurrentModificationException
08-24 13:37:25.968: ERROR/AndroidRuntime(6582): at java.util.AbstractList$SubAbstractList.listIterator(AbstractList.java:320)
08-24 13:37:25.968: ERROR/AndroidRuntime(6582): at java.util.AbstractList$SubAbstractList.iterator(AbstractList.java:307)
08-24 13:37:25.968: ERROR/AndroidRuntime(6582): at java.util.AbstractCollection.contains(AbstractCollection.java:128)
08-24 13:37:25.968: ERROR/AndroidRuntime(6582): at java.util.Collections$SynchronizedCollection.contains(Collections.java:432)
08-24 13:37:25.968: ERROR/AndroidRuntime(6582): at java.util.AbstractCollection.retainAll(AbstractCollection.java:319)
08-24 13:37:25.968: ERROR/AndroidRuntime(6582): at java.util.Vector.retainAll(Vector.java:856)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
检查在迭代时结构性修改 Vector(添加或删除)的代码 - 这很可能是您得到 CME。使用迭代器进行这样的修改以避免 CME
另外,我还建议使用 ArrayList而不是向量。
Check for a code where you structurally modify Vector (add or remove) while iterating it - this is most likely reason why you're getting CME. Use iterator to do such a modification to avoid CME
Also I second an advice to use ArrayList instead of Vector.
只是不要让其他任何人(除了持有向量的对象)访问该向量。这是确保除了持有对象之外没有人在迭代它时修改它的唯一方法。
从持有对象的方法返回并传递向量的副本,或返回/传递不可修改的版本(使用
Collections.unmodifyingList()
)。当然,返回不可修改的列表会破坏执行retainAll
调用的代码。旁注:
Vector
已过时,不应再使用。正如您刚刚注意到的,同步的事实并不能保护您免受并发访问错误的影响。因此使用 ArrayList 更好。Just don't let anyone else (than the object holding the vector) access the vector. This is the only way to make sure that nobody other than the holding object modifies it while iterating on it.
Return and pass copies of the vector from the methods of the holding object, or return/pass an unmodifiable version (using
Collections.unmodifiableList()
). Returning an unmodifiable list will break the code doing theretainAll
call, of course.Side note:
Vector
is obsolete and should not be used anymore. As you just noticed, the fact that it's synchronized doesn't shield you from concurrent access bugs. So using anArrayList
is better.