Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

ListenerList - a Better Way to Manage Your Event Listeners

DZone's Guide to

ListenerList - a Better Way to Manage Your Event Listeners

· Java Zone ·
Free Resource

Verify, standardize, and correct the Big 4 + more– name, email, phone and global addresses – try our Data Quality APIs now at Melissa Developer Portal!

You have published a listener interface and have a place where your clients register their listeners. There you typically code like this:

List<SomeEventListener> listeners = new ArrayList<SomeEventListener>(); 

public void addSomeEventListener(SomeEventListener listener) { 
    listeners.add(listener); 
} 

public void removeSomeEventListener(SomeEventListener listener) { 
    listeners.remove(listener); 
} 

public void fireSomeEvent(SomeEvent event) { 
    for (SomeEventListener listener : listeners) { 
        listener.eventOccured(event); 
    } 
}

The problem with this approach is two fold:

  1. Memory usage: The capacity of the ArrayList is always >= its size. So if you just have 200 listeners, there is a good chance that the memory might have been allocated for 300 elements
  2. Thread safety: Murphy's law will prove itself, and multi threaded bugs can be a pain in your back to debug. You have to properly sync all the write access and provide faster read only access for event firing operations.

To handle these two issues, Eclipse gives you a nice API: ListenerList class. Its meant for storing these kind of listeners, where any write modification to the underlying array (add, remove, clear) is synchronized and give access to the underlying array for faster read access. Memory is allocated only for the number of listeners registered.

The same above example can be rewritten as:

ListenerList listeners = new ListenerList(); 

public void addSomeEventListener(SomeEventListener listener) { 
    listeners.add(listener); 
} 

public void removeSomeEventListener(SomeEventListener listener) { 
    listeners.remove(listener); 
} 

public void fireSomeEvent(SomeEvent event) { 
    Object[] listenersArray = listeners.getListeners(); 
    for (int i = 0; i < listenersArray.length; i++) { 
        ((SomeEventListener)listenersArray[i]).eventOccured(event); 
    } 
}

 

ListenerList provides two ways of duplicate checking of the listeners: Equality and Identity. It can be specified in the constructor. Since the core Eclipse platform is in Java 1.4, you still can't use generics and foreach, but that shouldn't be a hindrance.

Question: Now that I do have a direct access to the underlying array, what if i manipulate it like this:

Object[] listenersArray = listeners.getListeners(); 
listenersArray[0] = null; 
listenersArray[1] = someEventListener5;

 

Well, the same thing happens when you shoot yourself in the foot :-)

 

Developers! Quickly and easily gain access to the tools and information you need! Explore, test and combine our data quality APIs at Melissa Developer Portal – home to tools that save time and boost revenue. Our APIs verify, standardize, and correct the Big 4 + more – name, email, phone and global addresses – to ensure accurate delivery, prevent blacklisting and identify risks in real-time.

Topics:

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}