Java 理解和解决ConcurrentModificationException
我正在处理一段遗留代码中的间歇性、难以重现的Java 理解和解决ConcurrentModificationException,java,concurrentmodification,Java,Concurrentmodification,我正在处理一段遗留代码中的间歇性、难以重现的ConcurrentModificationException: class LegacyCode { private final WeakHashMap<A, B> mItems = new WeakHashMap<A, B>(); public void someWork() { final List<A> copy = new LinkedList<A>();
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 each循环运行时调用了addItem(A)
或removietem(A)
问题
我对CME为何被抛出的理解正确吗
如果我将for each循环替换为:
final List<A> copy = new LinkedList<A>(mItems.keySet());
final List copy=newlinkedlist(mItems.keySet())代码>
此更改是否等同于我们将要替换的每个循环的更改?据我所知,这两个代码段都在copy
中创建了mItems.keySet()
的浅拷贝
我对CME为何被抛出的理解正确吗
当然。这正是正在发生的事情
如果我将for each循环替换为:
final List<A> copy = new LinkedList<A>(mItems.keySet());
解决此问题的最终列表,无需在代码中使用synchronized
。谢谢您的帮助。我理解为什么需要将for-each循环放在同步块中。但是,使addItem
和removietem
同步的原因是什么?@user3264740您需要读写双方同步
。否则,foreach
循环将自由获取锁,即使addItem
或removietem
可能正在进行。