Hi all,
I have a list of listeners, which may get added to or removed from by a thread at arbitrary times.
In order to prevent ConcurrentModificationException, when I notify listeners I first create an unmodifiableList, and then iterate though
that. I picked up that pattern from somewhere on this forum -- I don't know if it's a particularly good pattern or not.
However, I have a situations in which, when I remove from my list, I'm getting a ConcurrentModificationException from within the iterator of the new unmodifiableList. I'm confused because I'm not sure how anything is mofifying it.
My code is below. Any thoughts?
public void removeListener(Object listener){
if (listeners != null){
synchronized (listeners) { // not sure if this is necessary, doesn't affect either way
listeners.remove(listener);
}
}
}
private void notifyListeners(EnvironmentChangeEvent e){
List<Object> listenersList = Collections.unmodifiableList(listeners);
Iterator<Object> iterator = listenersList.iterator();
while (iterator.hasNext()){
Object listener = iterator.next(); // <------ line 1787 (see exception)
if (listener instanceof EnvironmentChangeListener)
((EnvironmentChangeListener)listener).environmentChanged(e);
}
}
}
----
Exception in thread "AWT-EventQueue-0" popdown
java.util.ConcurrentModificationException
at java.util.AbstractList$Itr.checkForComodification(AbstractList.java:372)
at java.util.AbstractList$Itr.next(AbstractList.java:343)
at java.util.Collections$UnmodifiableCollection$1.next(Collections.java:1010)
at org.concord.biologica.environment.Environment.notifyListeners(Environment.java:1787)