Listing 1

interface Event { /* whatever you need */ }

interface Listener { void receive(Generator from, Event event); }

interface Generator {
    void addListener(Listener listener);
    void removeListener(Listener listener);
}

class DefaultGenerator implements Generator {
    private ArrayList listeners = new ArrayList();
    private Object lock = new Object();
    public void addListener(Listener listener) {
        synchronized(lock) {
            if (listener != null &&
                ! listeners.contains(listener)) {
                listeners.add(listener);
            }
        }
    }

    public void removeListener(Listener listener) {
        synchronized(lock) {
            listeners.remove(listener);
        }
    }

    protected ArrayList cloneListeners() {
        synchronized(lock) {
            return (ArrayList) listeners.clone();
        }
    }

    protected void send(Event event) {
        ArrayList tmp = cloneListeners();
        for (Iterator i = tmp.iterator(); i.hasNext(); ) {
            ((Listener) i.next()).receive(this,event);
        }
    }
} // class DefaultGenerator


Listing 2

class DefaultGenerator implements Generator {
    private static final Listener[] NONE = new Listener[0];
    private Listener [] listeners = NONE;
    private Object lock = new Object();

    private boolean contains(Listener listener) {
        Listener[] tmp = listeners;
        for (int i=tmp.length-1; i>=0; --i)
            if (tmp[i] == listener) return true;
        return false;
    }

    // if we don't already have it,
    // add a listener to the front of a new listeners array.
    public void addListener(Listener listener) {
        synchronized(lock) {
            if (listener == null || contains(listener)) return;

            Listener[] tmp = new Listener[listeners.length+1];
            for (int i=tmp.length-1; i>0; --i) tmp[i]=listeners[i-1];
            tmp[0]=listener;

            listeners=tmp; // atomic update
        }
    }

    // if we do already have it,
    // remove a listener from a new listeners array.
    public void removeListener(Listener listener) {
        synchronized(lock) {
            if (!contains(listener)) return;

            Listener[] tmp = (listeners.length > 1) ?
                new Listener[listeners.length-1] : NONE;

            for (int i=listeners.length-1,j=i; i >= 0; --i)
                if (listeners[i] != listener)
                    tmp[--j]=listeners[i];

            listeners=tmp;  // atomic update
        }
    }

    protected final boolean listening() {
        return listeners != NONE;
    }

    protected final void send(Event event) {
        Listener[] tmp=listeners; // atomic read
        for (int i=tmp.length-1; i>=0; --i)
         {   tmp[i].receive(this,event);
        }
    }

} // class DefaultGenerator