我處理間歇,難以重現ConcurrentModificationException
中的遺留代碼塊:瞭解和解決ConcurrentModificationException的
class LegacyCode {
private final WeakHashMap<A, B> mItems = new WeakHashMap<A, B>();
public void someWork() {
final List<A> copy = new LinkedList<A>();
for (final A item : mItems.keySet()) {
copy.add(item);
}
for (final A item : copy) {
item.someMethod();
}
}
public void addItem(final A item) {
mItems.put(item, new B());
}
public void removeItem(final A item) {
mItems.remove(item);
}
}
的CME被拋出:
for (final A item : mItems.keySet()) {
copy.add(item);
}
我不完全確定爲什麼我們以這種方式創建copy
。 CME被拋出,因爲在for-each循環正在運行時調用addItem(A)
或removeItem(A)
。
問題
是我爲什麼CME被拋出正確的認識?
我會盡量避免CME如果我更換了,每個循環:
final List<A> copy = new LinkedList<A>(mItems.keySet());
將這種變化等同於for-each循環,我們將取代?據我所知,這兩個片段創建
mItems.keySet()
在copy
的淺拷貝。
感謝您解決這個問題。我明白爲什麼要將for-each循環放置在_synchronized_塊中。但是,使'addItem'和'removeItem'同步的原因是什麼? – user3264740
@ user3264740您需要讀取和寫入''synchronized''。否則,儘管'addItem'或'removeItem'可能正在進行,'foreach'循環會自由地獲得鎖。 – dasblinkenlight
令人驚歎的,謝謝! – user3264740