2011-08-24 49 views
1

我遇到问题。同时访问Vector我得到一个ConcurrentModificationException。我向所有向量迭代添加了同步块,但可能忘记了一个或另一个泄漏。ConcurrentModificationException修复问题

问题是,错误stacktrace显示的错误是一个调用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

Collection#SynchronizedCollection在迭代它时不会锁定备份集合。阅读[文档](http://download.oracle.com/javase/7/docs/api/java/util/Collections.html#synchronizedCollection%28java.util.Collection%29) –

+0

显示一些代码! –

回答

4

检查代码,你结构修改矢量(添加或删除),而迭代它 - 这就是为什么你得到CME最可能的原因。使用iterator做这样的修改,以避免CME

void unsafeMod(Vector data) { 
    for (Object o : data) { 
     if (o != null) { 
      data.remove(o); // may cause CME 
     } 
    } 
} 

而且我第二的advice使用ArrayList的,而不是矢量。

+1

其实,这是获得CME的唯一方法。可能涉及多个线程的事实不会改变这一点。类似,但不是这一个确切的副本http://stackoverflow.com/questions/602636/concurrentmodificationexception-and-a-hashmap/602660#602660 – Robin

1

不要让任何人(除了持有矢量对象)来访问向量。这是确保在迭代时保持对象以外的其他人不会修改它的唯一方法。

从持有对象的方法中返回并传递该向量的副本,或返回/传递一个不可修改的版本(使用Collections.unmodifiableList())。当然,返回一个不可修改的列表会破坏执行retainAll调用的代码。请注意:Vector已过时,不应再使用。正如你刚才注意到的那样,它同步的事实并不能保护你免受并发访问错误的影响。所以使用ArrayList更好。

+0

downvoter可以解释他downvote? –

+0

我对此表示歉意,因为CME并不是专门针对线程相关的问题,所以我原本低估了,因此我将对此发表评论。在仔细观察问题并意识到retainAll()方法发生错误后,我意识到在这种情况下,这是一个线程问题,不幸的是,由于太多时间过去了,我无法改变我的投票。 – Robin

+0

感谢您的解释。 –