ConcurrentModificationException in Multimap

1,090 views
Skip to first unread message

siva

unread,
Sep 28, 2010, 3:53:13 AM9/28/10
to guava-discuss
Just like ConcurrentHashMap is safe during iterator of keys for
HashMap. Is there any implementation for MultiMap?

We are using Multimap for keeping track of listeners on item. While
sending some event, if new subscriber is added for same item, for
which we are iterating and sending events,
ConcurrentModificationException is thrown. Is there any way to avoid
this.

static Multimap<String,String> getMap() {
Multimap<String, String> map = HashMultimap.create();
map.put("1", "1");
map.put("1", "2");
map.put("1", "3");
return map;
}

static void throwsException2() {
Multimap<String, String> map = getMap();

for (String string : map.get("1")) {
System.out.println("Get: "+string);
if (string.equals("2")) {
map.put("1", "4"); --> adding new element to same key
System.out.println("Added 3");
}
}

System.out.println(map.get("1"));
}

Exception:
Get: 3
Get: 2
Added 3
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.HashMap$HashIterator.nextEntry(HashMap.java:793)
at java.util.HashMap$KeyIterator.next(HashMap.java:828)
at com.google.common.collect.AbstractMultimap$WrappedCollection
$WrappedIterator.next(AbstractMultimap.java:516)
at
guava.MapConcurrentAccessTest.throwsException2(MapConcurrentAccessTest.java:
37)
at guava.MapConcurrentAccessTest.main(MapConcurrentAccessTest.java:
51)

Tim Peierls

unread,
Sep 28, 2010, 9:41:21 AM9/28/10
to siva, guava-discuss
The CME is because you're modifying the contents of the collection while iterating over it. You can avoid it by copying the contents of the collection returned by map.get(key) and iterating over that copy.

--tim


--
guava-...@googlegroups.com.
http://groups.google.com/group/guava-discuss?hl=en
unsubscribe: guava-discus...@googlegroups.com

This list is for discussion; for help, post to Stack Overflow instead:
http://stackoverflow.com/questions/ask
Use the tag "guava".

Jared Levy

unread,
Sep 28, 2010, 11:52:15 AM9/28/10
to Tim Peierls, siva, guava-discuss
Tim's suggestion is the best approach.

As another option, you could use the Multimaps.new*Multimap() methods with a Supplier that creates a CopyOnWriteArrayList or CopyOnWriteArraySet.
Reply all
Reply to author
Forward
0 new messages