Why are the methods in the Observable class are synchronized?
public synchronized void deleteObserver(Observer o) {
obs.removeElement(o);
}
I can't give you a definitive answer regarding why Observable
is implemented the way it is, but I can explain the effect.
While Vector
is a synchronized collection, it isn't synchronized while iterating. This is similar to the wrappers returned by the Collections.synchronizedXXX
methods. In order to safely iterate a Vector
in a concurrent context you need external synchronization. They accomplish this by using synchronized
methods. But if you look at notifyObservers
you'll see that the method isn't synchronized. However, if you look at the body of notifyObservers
you'll see a synchronized(this) {}
block. They do it this way because only part of the method body needs to be executed while holding the lock. If you're not aware, a synchronized
instance method is the same as using synchronized(this) {}
for the whole method.
The other effect caused by using synchronized
methods is that both the obs
field and the changed
field are guarded by the same lock. This keeps the state between those two fields consistent in a multi-threaded environment. Why they chose the enclosing instance as the lock, I have no idea, but that's what they did.
Note that, as near as I can tell, the Observable
class gives no guarantees regarding thread-safety in its documentation. This means the fact that it is thread-safe is an implementation detail.
Also note that Observable
has been deprecated since Java 9.