2011-08-24 48 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

感謝您的解釋。 –