ConcurrentModificationException修复问题

时间:2011-08-24 11:43:51

标签: java android multithreading thread-safety

我有问题。同时访问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)

2 个答案:

答案 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会更好。