Guava MultiMap and ConcurrentModificationException

Antoine Claval picture Antoine Claval · Oct 15, 2009 · Viewed 7.4k times · Source

I don't understand why I get a ConcurrentModificationException when I iterate through this multimap. I read the following entry, but I am not sure if I understood the whole thing. I tried to add a synchronized block. But my doubt is what to synchronize with, and when.

The multimap is a field and created like this :

private Multimap<GenericEvent, Command> eventMultiMap =   
   Multimaps.synchronizedMultimap(HashMultimap.<GenericEvent, Command> create());

and used like this :

eventMultiMap.put(event, command);

and like this ( I tried to synchronize this part on the map, but without success )

for (Entry<GenericEvent, Command> entry : eventMultiMap.entries()) {
    if (entry.getValue().equals(command)) {
        eventMultiMap.remove(entry.getKey(), entry.getValue());
        nbRemoved++;
    }
}

Answer

MHarris picture MHarris · Oct 15, 2009

Calling remove on a collection while you're iterating through it will cause a ConcurrentModificationException every time, even if it's all done in the same thread - the Right Thing to do is get an explicit iterator and call .remove() on that.

Edit: Modifying your example:

Iterator<Map.Entry<GenericEvent, Command>> i = eventMultiMap.entries().iterator();
while (i.hasNext()) {
    if (i.next().getValue().equals(command)) {
        i.remove();
        nbRemoved++;
    }
}