Reputation: 12794
What am I getting a ConcurrentModificationException
with this code? I have a synchronized(listeners) lock.
private void notifyListeners(MediumRendition rendition) {
if (rendition == null) return;
synchronized (listeners) {
for (RenditionEventListener l : listeners) {
if (l.renditionType.equals(rendition.getType()) && l.mediumId == rendition.getMediumId()) {
l.listener.onRendition(rendition);
}
}
}
}
public void put(String renditionType, long mediumId, MediumRendition rendition) {
HashMap<Long, MediumRendition> l = list.get(renditionType);
if (l == null) {
l = new HashMap<Long, MediumRendition>();
list.put(renditionType, l);
}
l.put(mediumId, rendition);
notifyListeners(rendition);
}
public void addRenditionListener(String renditionType, long mediumId, RenditionListener listener) {
synchronized (listeners) {
listeners.add(new RenditionEventListener(renditionType, mediumId, listener));
}
}
01-30 16:47:55.147 6953 6974 E AndroidRuntime: FATAL EXCEPTION: Thread 1 01-30 16:47:55.147 6953 6974 E AndroidRuntime: java.util.ConcurrentModificationException 01-30 16:47:55.147 6953 6974 E AndroidRuntime: at java.util.ArrayList$ArrayListIterator.next(ArrayList.java:573) 01-30 16:47:55.147 6953 6974 E AndroidRuntime: at com..vos.RenditionList.notifyListeners(RenditionList.java:79) 01-30 16:47:55.147 6953 6974 E AndroidRuntime: at com.t.vos.RenditionList.put(RenditionList.java:41) 01-30 16:47:55.147 6953 6974 E AndroidRuntime: at com.*.controllers.OmwController$6.run(OmwController.java:212)
SOLVED: Apparently I was removing. See below.
Upvotes: 0
Views: 252
Reputation: 314
Concurrency is kind of tricky. In the context of your application, though, you may not see that you are not modifying the list but it is getting modified somewhere when you call
l.listener.onRendition(rendition);
The possible solutions are as below.
ConcurrentLinkedQueue
instead of ArrayList
. You don't need to write synchronize block if you use this collection. This is the simplest solution.CopyOnWriteArrayList
instead of ArrayList
. When you stash listeners, it is preferable way to use CopyOnWriteArrayList
instead of ArrayList
.Upvotes: 2
Reputation: 9317
The exception indicates that listeners might have been modified from another thread. So you should check if it is being modified without synchronization somewhere else.
Also check if the implementation of onRendition() removes listener from list as that could be another cause if multiple threads are not involved.
Upvotes: 5