我处理间歇,难以重现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