Meaningless Drivel is fun!*
The moose likes Programmer Certification (SCJP/OCPJP) and the fly likes K&B notifyAll( ) Example Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of OCA/OCP Java SE 7 Programmer I & II Study Guide this week in the OCPJP forum!
JavaRanch » Java Forums » Certification » Programmer Certification (SCJP/OCPJP)
Bookmark "K&B notifyAll( ) Example" Watch "K&B notifyAll( ) Example" New topic
Author

K&B notifyAll( ) Example

Sindhur Sat
Greenhorn

Joined: Feb 23, 2004
Posts: 23
There has been a lot of discussion on this example and I have more the add.
I removed the notifyAll() and replaced it with notify() in the the run() method of the Calculator thread and there is absolutely no difference in the output (I executed it on three different operating systems).
Also I tried to add a sleep() to make sure that all three threads are waiting before the calculator starts and hence there are three threads in the wait pool of the object calc. When notify() is called one of the three threads has to be woken up and the other two should still continue to wait right? Wrong!! Thats not what is happening.
Why do the other two threads also get notified? I think I am missing something very important.
I know the book mentions

Note that if the run() method used notify() instead of notifyAll(), there would be a chance that only one reader would be notified instead of all the readers.

Is there ever a situation where only one thread is notified? I could not find one.
I add the code here:

Please Advice,
Sindhur.
Bijesh Krishnadas
Ranch Hand

Joined: Aug 08, 2002
Posts: 31
Does someone have an answer to this? I've been waiting to see it answered by the gurus.
Bijesh
Richard Quist
Ranch Hand

Joined: Feb 18, 2004
Posts: 96
I confirmed this behavior on Windows using J2SE 1.4 ...and it certainly seems to run counter to the documentation for notify(). According to the 2nd edition of the Java Language Spec:
The notify method should be called for an object only when the current thread has already locked the object�s lock. If the wait set for the object is not empty, then some arbitrarily chosen thread is removed from the wait set and reenabled for thread scheduling. (Of course, that thread will not be able to proceed until the current thread relinquishes the object�s lock.)

and...
The notifyAll method should be called for an object only when the current thread has already locked the object�s lock. [B} Every thread [B] in the wait set for the object is removed from the wait set and re-enabled for thread scheduling. (Of course, those threads will not be able to proceed until the current thread relinquishes the object�s lock.)

Then, just for fun, I commented out the call to notify()....and the program still completed. I expected that it would wait forever...
[ March 03, 2004: Message edited by: Richard Quist ]

Rich
SCJP 1.4
Sindhur Sat
Greenhorn

Joined: Feb 23, 2004
Posts: 23
Richard,
You added a new twist to an already twisted problem. I tried removing the notify() like you said and guess what... it still worked exactly the way it worked with all the notify() calls. All this without even adding a timeout in the wait() call.
Interesting!!!
Sindhur.
[ March 03, 2004: Message edited by: Sindhur Sat ]
[ March 03, 2004: Message edited by: Sindhur Sat ]
Bijesh Krishnadas
Ranch Hand

Joined: Aug 08, 2002
Posts: 31
I have a hypothesis here:
1) If the object being synchronised(syncObj) is a thread by itself, then merely running this object's thread to completion does something similar to notifyAll()
below is the research I did.

Running the code as is results in all Reader threads waiting forever.
Running with line A uncommented wakes up exactly one thread.
Running with line B uncommented wakes up all threads.
Running with line C uncommented wakes up all threads.
So wat say ppl? Is this another weird but true or does the JLS actually talk about this.
Gurus, ur thoughts, plzzz.
Bijesh
Prabath Siriwardena
Greenhorn

Joined: Mar 27, 2004
Posts: 15
ASSUME :
ThreadA, ThreadB and ThreadC are Reader Threads.
CalculatorThread and CalThread are Calculator Threads.
Case I
ThreadA, ThreadB, ThreadC all wait on CalculatorThread to finish a certain task.
CalculatorThread has a notify() call inside it’s run() just after the expected task of Reader threads completed. But Calculator thread can run beyond that.
CalculatorThread is still alive (not dead) when ThreaA,ThreadB,ThreadC hit their wait() call.

1)Only one Reader thread will be notified.(say ThreadB)
2)It will resume operations as soon as CalculatorThread notified and it exits the synchronized block, where “notify()” resides.
3)Other Reader threads will wait(). But now their wait() method behaves as the yield() method. ( Exactly as yield. It won’t release any locks it has now. But remember it has already released the lock on CalculatorThreard object, at the time it hit the wait() call)
4)So as soon as CalculatorThread exits it’s run() method, ThreadA & ThreadC resume their operaions.

Case I I
ThreadA, ThreadB, ThreadC all wait on CalculatorThread to finish a certain task.
CalculatorThread has a notify() ( or may not have a notify()) call inside it’s run() just after the expected task of Reader threads completed. But Calculator thread can run beyond that.
CalculatorThread is not alive (dead) when ThreaA,ThreadB,ThreadC hit their wait() call.
1)NO Reader thread will be notified.
2)All reader threads will wait(). But now their wait() method behaves as the sleep() method. ( Exactly as sleep(). It won’t release any locks it has now. But remember it has already released the lock on CalculatorThreard object, at the time it hit the wait() call)

Case III
ThreadA, ThreadB, ThreadC all wait on CalculatorThread to finish a certain task.
CalculatorThread has a notify() ( or may not have a notify()) call inside it’s run() just after the expected task of Reader threads completed. But Calculator thread can run beyond that.
CalculatorThread is not alive (dead) when ThreaA,ThreadB,ThreadC hit their wait() call.
But CalThread is alive, and contains a notify() ( or may not have a notify())call inside it’s run() just after the expected task of Reader threads completed.
1)NO Reader thread will be notified, because none of them waits on CalThread object.
2)All reader threads will wait(). But now their wait() method behaves as the sleep() method. ( Exactly as sleep(). It won’t release any locks it has now. But remember it has already released the lock on CalculatorThreard object, at the time it hit the wait() call)
Case I V
ThreadA, ThreadB, ThreadC all wait on CalculatorThread to finish a certain task.
CalculatorThread has a notifyAll() call inside it’s run() just after the expected task of Reader threads completed. But Calculator thread can run beyond that.
CalculatorThread is still alive (not dead) when ThreaA,ThreadB,ThreadC hit their wait() call.

1)All Reader threads will be notified.
2)All will resume operations as soon as CalculatorThread notified and it exits the synchronized block, where “notifyAll()” resides.
Case V
ThreadA, ThreadB, ThreadC all wait on CalculatorThread to finish a certain task.
CalculatorThread has NO notify() or notifyAll() calls inside it’s run().
CalculatorThread is still alive (not dead) when ThreaA,ThreadB,ThreadC hit their wait() call.

1)No Reader thread will be notified.
2)All Reader threads will wait(). But now their wait() method behaves as the yield() method. ( Exactly as yield. It won’t release any locks it has now. But remember it has already released the lock on CalculatorThreard object, at the time it hit the wait() call)
3)So as soon as CalculatorThread exits it’s run() method, all Reader threads resume their operations.


<a href="http://psiriwardena.blogspot.com/" target="_blank" rel="nofollow">http://psiriwardena.blogspot.com/</a><br />B.Sc(Eng),SCJP,SCWCD,SCBCD,SCDJWS,<br />MCSD,OCA,CCNA.BCS,ACS
 
wood burning stoves
 
subject: K&B notifyAll( ) Example