Related: Does java have a "LinkedConcurrentHashMap" data structure?
I am looking for a collection class to hold references to event listeners.
Ideally I would like the collection to have the following properties (in order of priority):
HashSet
whose iterator may return elements in the wrong order.WeakReference
s so that the listener list does not prevent the listeners from being garbage-collected.Set
, so duplicates are automatically removed.Iterator
is a thread-safe snapshot of the collection, unaffected by the addition of new listeners. Also allows events to be delivered on multiple threads. (This is not essential - I could iterate over a clone of the set instead.)I am aware of some classes that satisfy some but not all of these criteria. Examples:
java.util.LinkedHashSet
(#1 and #3)java.util.WeakHashMap
, wrapped by Collections.newSetFromMap
(#2 and #3)javax.swing.event.EventListenerList
(needs some extra synchronization) (#1 and #4)java.util.concurrent.CopyOnWriteArraySet
(#1, #3 and #4)But nothing with both #1 and #2. Does class like this exist in a library somewhere?
You could use WeakListeners (see http://bits.netbeans.org/dev/javadoc/org-openide-util/org/openide/util/WeakListeners.html) and CopyOnWriteArraySet.
remove(ListenerType listener)
method in your event source.In your register(SomeListener listener)
method, add a WeakListener to the collection instead:
listenerCollection.put((ListenerType)WeakListeners.create (
ListenerType.class, listener, this));
When the real listener is removed from memory, the weak listener will be notified, and it will unregister itself. (This is why it needs the reference to the source (this
) for the registration.) The unregistration is done using reflection by calling the method remove of the source.