Order of Observer notification with notifyObservers()

Viewed 985

I have this following code:

public class MyObservable extends Observable {
    // ...
    public void doSomething() {
        // do stuff
        setChanged();
        notifyObservers();
    }
}

public class A implements Observer {
    public void update(Observable o, Object arg) {
        // do something
    }
}

public class B implements Observer {
    public void update(Observable o, Object arg) {
        // do something
    }
}

And the main function:

public static void main(String[] args) {
    MyOvervable a = new MyObservable();
    a.addObserver(new A());
    a.addOberser(new B());
    a.doSomething();
}

Is the order the update functions are called by notifyObservers() the same order as I added the observers with addObserver()?

3 Answers

Javadoc for Observable says that notification is in the order listeners were registered, however this is incorrect - notification is actually made in reverse order.

Code excerpts with explanatory comments:

// addObserver() adds last-most at end of the list
public synchronized void addObserver(Observer o) {
    ..
    obs.addElement(o);
}

public void notifyObservers(Object arg) {
    ..
    // notifyObservers iterates backwards; last-most first.
    for (int i = arrLocal.length-1; i>=0; i--)
        ((Observer)arrLocal[i]).update(this, arg);
}

I filed a bug report -- https://bugs.java.com/bugdatabase/view_bug.do?bug_id=JDK-8214760 -- however due to Observable being deprecated, it has been closed as 'will not fix'.

My belief is that the behavior as implemented is stable and will not change; changing the order would probably break compatibility for many applications that use this.

Yes it is. Here's an excerpt from java java.util.Observable class.

private Vector<Observer> obs;

arrLocal = obs.toArray();

for (int i = arrLocal.length-1; i>=0; i--)
    ((Observer)arrLocal[i]).update(this, arg);

Vector is index based and backed up by an array internally. Vector maintains the insertion order of element. Means you can assume that you will get the object in the order you have inserted if you iterate over a Vector.

So the answer to your question is: YES

According to Oracle's docs:

The order in which notifications will be delivered is unspecified. The default implementation provided in the Observable class will notify Observers in the order in which they registered interest, but subclasses may change this order, use no guaranteed order, deliver notifications on separate threads, or may guarantee that their subclass follows this order, as they choose.

Related