Why is Observerable.setChanged() synchronized

T

tomerbd1

I'm looking at java.util.Observable code and I noticed that
setChanged() is synchronized, however i can't figure out why... anyone
can help me?

protected synchronized void setChanged() {
changed = true;
}


Thanks

Tomer
 
M

Mike Schilling

I'm looking at java.util.Observable code and I noticed that
setChanged() is synchronized, however i can't figure out why... anyone
can help me?

protected synchronized void setChanged() {
changed = true;
}


Presumably, to ensure that the new value of "changed" is visible in other
threads.
 
T

Thomas Hawtin

I'm looking at java.util.Observable code and I noticed that
setChanged() is synchronized, however i can't figure out why... anyone
can help me?

protected synchronized void setChanged() {
changed = true;
}

Firstly Observable is a really bad class, and you should think about
using Java 1.1-style events instead.

It's synchronised because it is involves the object state that may be
used by multiple threads. Observable uses Vector which is "thread-safe",
yet Observable still needs to use synchronisation because there are
operations that need to be atomic that Vector does not support. Likewise
the thread-safety of Observable is pretty useless - you need to do
setChanged and notifyObservers(Object) together. Only you shouldn't call
notifyObservers with a locks held - oops.

Tom Hawtin
 
T

Thomas Weidenfeller

I'm looking at java.util.Observable code and I noticed that
setChanged() is synchronized, however i can't figure out why... anyone
can help me?

protected synchronized void setChanged() {
changed = true;
}

A couple of remarks, non of which might apply:

(a) When studying synchronization (multithreading behavior), you have to
look at all methods who have access to the particular data, not only at
one isolated method. So there might (or might not) be some other code in
Observable that depends on setChanged() being synchronized.

(b) One can see such things in several of the original Java 1.0 classes,
e.g. the pre-collection classes like Hashtable. My guess is that the
original Java designers were a little bit naive when it came to
multithreading and synchronization. Synchronizing setChanged() might (or
might not) have been an overhasty design decision.

(c) Observer/Observable work as advertised, but are often just to simple
or to clumsy for real world tasks. If they don't cut it for you, do your
own.

/Thomas
 
M

Mike Schilling

Thomas Weidenfeller said:
A couple of remarks, non of which might apply:
(b) One can see such things in several of the original Java 1.0 classes,
e.g. the pre-collection classes like Hashtable. My guess is that the
original Java designers were a little bit naive when it came to
multithreading and synchronization.

Or, more likely, they understood it quite well

If you want a change to the state of an object to be visible in all threads,
you need to synchronize both the code that makes the change and the code
that checks for the change. Observable does this correctly:

protected synchronized void setChanged() {
changed = true;
}

protected synchronized void clearChanged() {
changed = false;
}

public synchronized boolean hasChanged() {
return changed;
}

Without the synchronization, there is no guarantee under the Java memory
model that the result of a call to setChanged() in thread 1 will result in
hasChanged() returning "true" in thread 2.
 
T

Thomas Hawtin

Mike said:
Or, more likely, they understood it quite well

Understood the mechanism, but were naive about the practice.
If you want a change to the state of an object to be visible in all threads,
you need to synchronize both the code that makes the change and the code
that checks for the change. Observable does this correctly:

Which I think is Thomas Weidenfeller's point (a).

Say we were actually proposing to use this effort in a thread-safe
class. The fields of our subclass will also need to be guarded, and so
it rather makes sense to call setChanged under out lock (probably the
same one) anyway.

Ignoring mixing the subclass and Observable class locking for a moment,
to modify stuff, we'll have code like:

synchronized (this) {
++this.x;
}
setChanged();
notifyObservers("x");

Suppose we had another piece of code with x replaced by y. The might be
called at the same time. There should be two observations: one with "x"
and one with "y". But both threads may call setChanged first, then it
becomes a race to notify.

So: Threading can be difficult. Events can be difficult. Mixing
threading and events is challenging. See Swing for an example **** up.

Tom Hawtin
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,269
Messages
2,571,098
Members
48,773
Latest member
Kaybee

Latest Threads

Top