我有问题。同时访问Vector我得到一个ConcurrentModificationException。我在所有向量迭代中添加了synchronized块,但可能忘记了一个或者有另一个泄漏。
问题在于错误堆栈跟踪显示的错误是对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)
答案 0 :(得分:4)
在迭代时检查结构修改向量(添加或删除)的代码 - 这很可能是您获得CME的原因。使用迭代器进行此类修改以避免CME
void unsafeMod(Vector data) {
for (Object o : data) {
if (o != null) {
data.remove(o); // may cause CME
}
}
}
另外,我使用ArrayList而不是Vector。
来使用advice答案 1 :(得分:1)
不要让任何人(比持有向量的对象)访问向量。这是确保除了持有对象之外的任何人在迭代时修改它的唯一方法。
从保持对象的方法返回并传递向量的副本,或返回/传递不可修改的版本(使用Collections.unmodifiableList()
)。当然,返回不可修改的列表会破坏执行retainAll
调用的代码。
旁注:Vector
已过时,不应再使用了。正如您刚刚注意到的那样,它同步的事实并不能保护您免受并发访问错误的影响。因此,使用ArrayList
会更好。