• Post Reply Bookmark Topic Watch Topic
  • New Topic

wait/notifyAll() a bit like addObserver(this) and notifyObservers() ?  RSS feed

 
Anonymous
Ranch Hand
Posts: 18944
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I seek clarification of a mock question.
Without supplying all relevant context (since I don't have it readily accessible now -- from Brogden CD-ROM, 2nd mock), the point is how to get one thread to get another to stop waiting.
three options I chose (only two of which, #1 and #3, deemed correct) are as follows:
1) b.interrupt();
2) synchronize(a) a.notifyAll();
3) synchronize(b) b.notifyAll();
I'd thought #2 is also corrrect, apparently because I'd misconstrued the meaning of "all" in notifyAll(). It's false, in this case, apparently because the Thread that needs to be made to stop waiting is NOT waiting for the lock on "a".
I'm now assuming that the, so to speak, "waiters" on a given object's lock are known to the given object much as an Observable knows (has references to) its Observers (which it got thanks to calls like Observable.addObserver(this)? -- some Thread-related version of this within "wait()" ?), and that a call to notifyAll() involves something like a call to notifyObservers(), which iterates through a list of Observers, (in case of Threads, "the wait-list"?) calling each one's "update()" method, except that, in the case of Threads, a method is called that sets the "waiter's" notify flag to true, somewhat like the way an object's "interrupted" flag gets set to true.
These are largely inferences of mine.
I seek confirmation or refutation thereof.
 
Marcela Blei
Ranch Hand
Posts: 477
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I don�t agree. For me the only valid answer is a, since notify() doesn�t necessarily produce a stop to other thread. Supose that the one who calls the notify all has a high priority so it continue working with the processor until the end of it�s job, when it finishes, then other thread tries to get the lock on the object in question.
 
Anonymous
Ranch Hand
Posts: 18944
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Larry;
I infer that the question in your post had the thread waiting on "b" and not "a". Given this, #3 will wake the thread, along with any other threads waiting on b's lock. Marcela, note that the question said "stop waiting", not "begin running".
Let's put off #1 for a minute, and consider how synchronization works. Any object in Java can serve as a monitor, which is defined as an entity with a single lock and a wait set. Waiting threads sit in the wait set until one of three things happens: their wait expires, they are interrupted, or they are removed as a result of a call to the monitor object's <code>notify</code> or <code>notifyAll</code> method. Once they leave the wait set, they enter contention for the monitor's lock. The comparison of the wait set with an <code>Observable</code> object's set of <code>Observer</code>s is OK as far as it goes, but it's an incomplete analogy because it doesn't account for expired waits or interruptions.
About #1: I thought "b" was the monitor object, not a thread. <code>interrupt</code> is a <code>Thread</code> method, not a monitor (i.e. <code>Object</code>) method. Unless the question has the thread synchronizing on itself (which would be quite confusing - see Rahul's clever puzzler) then #1 won't even compile.
Further remarks: I don't think a <code>Thread</code> has a "notify flag" - maintaining the wait set is the job of the monitor and the JVM. Also, the only objects with "interrupted flags" are <code>Thread</code>s.
[This message has been edited by jply (edited August 28, 2000).]
 
Anonymous
Ranch Hand
Posts: 18944
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
assume:
synchronized(b) // in this or some other method of "a"
{
try
{
b.wait();
}
catch(InterruptedException ex) {}
}
============================================
(in some other Thread (or Runnable) object ...)
If this other Thread wants the currently waiting one to stop waiting, it can do the following:
a.interrupt();
synchronized(b) (b.notifyAll();}
but the following will NOT have that effect:
synchronized(a) {a.notifyAll();}
because:
in case of "a.interrupt();",
this will make control jump out of the wait()-call in
"a" and go to its catch-block for InterruptedException
in case of "synchronized(b) {b.notifyAll();}",
"b" will notify all threads waiting on it (including the
thread running in "a")
in case of "synchronized(a) a.notifyAll();}",
"a" will notify all threads waiting on it (which, in this
case, amounts to no threads -- in particular not the
thread running in "a"); the thread running in "a" is not
trying to get the lock on "a", so it's not in "a"'s "wait-set"
and consequently will not be notified.

Yes? No?
 
Anonymous
Ranch Hand
Posts: 18944
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Close.
I take it "a" is the class containing the synchronized code block and "b" is some other object being used as a monitor. Let's call the thread "t" - this is the thread that is executing the synchronized code in "a".
You don't call <code>a.interrupt()</code>, you call <code>t.interrupt()</code>. This will cause the thread to leave the wait set of "a" and enter contention for that object's lock.
Your other two points look correct to me.
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!