Java.next -- Four languages that represent the future of Java
Blogger Stuart Halloway has begun a series of posts on trends that point to the future of the Java platform. In his first post, he compares Clojure, Groovy, JRuby, and Scala -- four wildly different languages that nonetheless all play together in the JRE. Find out what unites these languages and what they can tell us about the future of Java-based development ...

Newsletter sign-up

Sign up for our technology specific newsletters.

Enterprise Java
View all newsletters

Email Address:

Speed up listener notification

Discover the fastest way to notify event listeners defined by the JavaBeans 1.01 specification

Java 1.1, Swing, JavaBeans, and the InfoBus spec all use the delegation event model described in the JavaBeans 1.01 specification for event registration and notification (see the Resources section below for more information). Under this model, when implementing a JavaBean, you have to implement event registration and event notification code in the bean. In this article, we'll compare the performance of several different techniques for implementing the event registration and notification code. The article is organized into two parts. The first covers the requirements for event delivery and explains the basic technique for implementing fast listener notification code. The second builds a test harness and several test cases that compare the performance of the various implementations. The article concludes by giving advice on when you should apply the optimizations presented.

Requirements for event notification

Let's begin with a quick review of listener notification, which is in fact just another name for event delivery. Event delivery is in turn fully described in Section 6.6 of the JavaBeans 1.01 specification (see Resources).

When a JavaBean wants to trigger an event, it notifies all registered listeners by calling the event's method on the registered listeners' listener interfaces. Listeners register with a JavaBean by calling the bean's add<ListenerType>(<ListenerType> listener)method.

Section 6.5.1 of the JavaBeans 1.01 specification contains an example of event-listener registration and event-listener notification. The source code from this example forms the basis of my analysis:

public interface ModelChangedListener extends
    java.util.EventListener
{
    void modelChanged(EventObject e);
}
                   
public abstract class Model { private Vector listeners = new Vector(); // list of Listeners public synchronized void addModelChangedListener(ModelChangedListener mcl) { listeners.addElement(mcl); } public synchronized void removeModelChangedListener(ModelChangedListener mcl) { listeners.removeElement(mcl); } protected void notifyModelChanged() { Vector l; EventObject e = new EventObject(this); // Must copy the Vector here in order to freeze the state of the // set of EventListeners the event should be delivered to prior // to delivery. This ensures that any changes made to the Vector // from a target listener's method, during the delivery of this // event will not take effect until after the event is delivered synchronized(this) { l = (Vector)listeners.clone(); } for (int i = 0; i < l.size(); i++) { // deliver it! ((ModelChangedListener)l.elementAt(i)).modelChanged(e); } } }


The JavaBeans 1.01 specification specifically states that the list of listeners can potentially be updated at the same time that those very listeners are being notified of events. The target listener may modify the listener list, or a different thread may attempt to add or remove listeners.

Thus, the JavaBeans 1.01 specification allows for different implementations. An implementation can make a copy of the list of listeners, and then notify only the listeners in the copied list of events; alternately, an implementation can use the current (and potentially changing) list as it proceeds with the notifications. Using a copy means that additions and removals that take place during the notification process do not alter the list of listeners being notified of the current event. Notice that the example above uses just such a copy implementation.

Resources