Thanks for the response. I found another thread discussing the same thing which may provide some background:
Your response is on the right track. I have an object that needs to inform others when it changes. It allows others to register a listener. E.g. object is a model, various other objects need to know when the model changes. The listeners are stored in some collection (my suggestion was a CopyOnWriteArrayList, your response used a List). When a change occurs, the object must call each listener.
If you just store the listeners in a list, and use an iterator to go through them, you are at risk of getting a Concurrent ModificationException if either another thread or one of the listeners itself either add or remove a listener. I can see a few ways to prevent this.
1) synchronize on the list (call this lock A) when doing an add, remove or looping through the list (as your response suggested).This introduces the risk of deadlock, e.g.
a) thread A has lock A and is looping through the listeners
b) thread B has lock B, tries to add/remove a listener and therefore blocks on lock A
c) a listener (running in thread A) tries to acquire lock B
2) use a CopyOnWriteArrayList to store the listeners. This introduces the problem of my original post.
a) thread A is looping through the listeners (no lock involved)
b) thread B (or code called from the listener) removes a listener that hasn't yet been called.
c) thread A is still using an old copy of the list of listeners (since the COWAL uses a snapshot iterator), so it then calls the listener that was already removed.
I'm coming to the conclusion you can't make this bullet proof without placing some restrictions on the listeners. For example, the listener can't do anything that will add/remove a listener. Or the listener must be robust against being called after it was removed.