I'm dealing with an intermittent, hard to reproduce ConcurrentModificationException in a chunk of legacy code:
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);
}
}
The CME is being thrown in:
for (final A item : mItems.keySet()) {
copy.add(item);
}
I'm not entirely sure as to why we create copy in this manner. The CME is thrown because either addItem(A) or removeItem(A) is called while the for-each loop is running.
Questions
Is my understanding of why CME is being thrown correct?
Will I avoid CME if I replace the for-each loop with:
final List<A> copy = new LinkedList<A>(mItems.keySet());Will this change be equivalent to the for-each loop we will be replacing? As far as I can tell, both snippets create a shallow copy of
mItems.keySet()incopy.