my dog learned polymorphism*
The moose likes Programmer Certification (SCJP/OCPJP) and the fly likes notify() and notifyAll() Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Certification » Programmer Certification (SCJP/OCPJP)
Bookmark "notify() and notifyAll()" Watch "notify() and notifyAll()" New topic
Author

notify() and notifyAll()

Vidya Ram
Ranch Hand

Joined: Apr 22, 2003
Posts: 62
This is an example about notifyAll() in Sierra-Bates study guide
class Calculator extends Thread{
int total;

public void run()
synchronized(this) {
for (int i=0;i<=100;i++){ total+=i;}
notifyAll();
}
}
}
class Reader extends Thread {
Calculator c;
public Reader(Calculator calc) { c = calc;}

public void run() {
synchronized(c) {
try{ //have to try/catch or declare...else compiler error...
System.out.println("Waiting for calculation...");
c.wait();
} catch(InterruptedException e) {}
}
System.out.println("Total is " + c.total);
}
public static void main(String args[]) {
Calculator calculator = new Calculator();

new Reader(calculator).start();
new Reader(calculator).start();
new Reader(calculator).start();
calculator.start();
}
}
And the output will be
Waiting for calculation...
Waiting for calculation...
Waiting for calculation...
Total is 5050
Total is 5050
Total is 5050

In the above code, even if I change notifyAll() to notify(), I'm getting the same result.
But I expected that with notify() only one Reader thread will be notified and will come to completion while the other 2 will be waiting forever.
Where Am I wrong???
[ April 30, 2003: Message edited by: Vidya Ram ]
G Nadeem
Ranch Hand

Joined: Apr 25, 2003
Posts: 48
hi Vidya,
let me try
i dont understand why u expect remaining thread to wait for ever in the 'waiting pool' of the monitor when u change notifyAll() to notify() or vice versa; it only effects which competing thread from the pool will be given a go-ahead . when first thread will finish and call notify()/notifyAll(), there will be only two threads left in the pool and one of them will do its stuff. simimlar second will call notifyAll()/notifyAll() to let the third and final thread to do the stuff and end the story.
hope it is valid and helpful. :roll:
Jose Botella
Ranch Hand

Joined: Jul 03, 2001
Posts: 2120
Welcome to the Ranch Nadeem and Vidya.
Never invoke wait without a loop. It seems that the implementation of Threads allows for spurious wakes-ups of threads. That is, as if spurious notify are called automatically. Place the wait in a loop that test the condition on which the tread is waiting on. If a spurious wake-up happens it would check that the condition is not met and it would go back to wait:

Now it prints:
Waiting for calculation...
Waiting for calculation...
Waiting for calculation...
Total is 5050


SCJP2. Please Indent your code using UBB Code
Jose Botella
Ranch Hand

Joined: Jul 03, 2001
Posts: 2120
By the way, this is a good one about threads:

Output:
Waiting for calculation...
Total is 0
Waiting for calculation...
Waiting for calculation...
Total is 5050
Can anybody explain the output?
Vidya Ram
Ranch Hand

Joined: Apr 22, 2003
Posts: 62
Thank you Jose for the reply. I understand it now.
In your second example, is that output because of the fact that the synchronized code in the main thread of the Reader runs before any other Reader thread gets to run. So it sets the waitingCondition flag to true and issues a notify which will not have any effect as no other thread is waiting in the pool then. After this, when a Reader thread is given a chance to run, it never waits for the lock as the flag was set to true and thus gives the output Total is 0.
Am I right?
But I have one more doubt, in my first example, could there be chances that the Calculator thread was given the chance to run before any Reader thread(thus issuing a notify before any Reader waits for the lock), then there will be a chance that all three Reader threads will be waiting in the pool forever?
I think this could happen as least is guaranteed when it comes to threads !

Thanks for the help.
Vidya.
[ May 01, 2003: Message edited by: Vidya Ram ]
Yuan Ye
Ranch Hand

Joined: Mar 05, 2003
Posts: 172
But I have one more doubt, in my first example, could there be chances that the Calculator thread was given the chance to run before any Reader thread(thus issuing a notify before any Reader waits for the lock), then there will be a chance that all three Reader threads will be waiting in the pool forever?
I think this could happen as least is guaranteed when it comes to threads !

I also have this doubt when I read the example. Could any one please tell us would that happen?
Barry Gaunt
Ranch Hand

Joined: Aug 03, 2002
Posts: 7729
If you check the errata for the book, you will find that the starting of the Calculator thread has been moved up above the starting of the Reader threads.
As David Willis below says, this is wrong, sorry.
[ May 02, 2003: Message edited by: Barry Gaunt ]

Ask a Meaningful Question and HowToAskQuestionsOnJavaRanch
Getting someone to think and try something out is much more useful than just telling them the answer.
David Willis
Greenhorn

Joined: Apr 16, 2003
Posts: 18
Barry,
You have it mixed up. The start of the Calulator thread should be moved DOWN below the three new statements.
Barry Gaunt
Ranch Hand

Joined: Aug 03, 2002
Posts: 7729
Originally posted by David Willis:
Barry,
You have it mixed up. The start of the Calulator thread should be moved DOWN below the three new statements.

Oh, thanks David, that was the corrected version . I did see a post once about the original question and assumed this was the same thing.
Barry Gaunt
Ranch Hand

Joined: Aug 03, 2002
Posts: 7729
It's interesting, I duplicated the starting of the Reader threads until I had 3 to 4 hundred of them. They all woke up! That's a little bit more than spurious wakes.
So is the JVM implicity changing the notify() into a notifyAll(). Got the source Luke?
Jose Botella
Ranch Hand

Joined: Jul 03, 2001
Posts: 2120
I left out all the notify calls and still the three Readers are woken. It seems that afer all the unwanted wake ups are to blame, though they are not spurious but continous
Some more tests:
a) if thread main is calling calculator.run() only one thread is awaken by notify. I placed a sleep of 2 seconds between the start of the last Reader and calculator.run()
b) if thread main creates another thread to start the calculator, again only one thread is awaken by a notify.
_______________________________________________
Yuan yee, you are right. There is no absolute guarantee about which thread will be started first.
_______________________________________________
Regarding my example. I am not pretty sure now.
:roll: . I am tired now I will be posting later.
Jose Botella
Ranch Hand

Joined: Jul 03, 2001
Posts: 2120
Regarding my example:
As "Total is 0" shows, a Reader thread is started before the Calculator one. Then two notify calls are made. Only one Reader, of the remaining two, can proceed. This is so because, even though the two Readers are woken up, only one can grab the lock. The other is locked. When the lock is finally released the third Reader thread grabs it; but it finds that waitingCondition is false, thus the while loop forces it to wait again. This time for ever. The trick is to understand that even though waitingCondition is made true twice, it is done so in a synchronized method. Thus there is no chance to it to become false between the points where it is true. This is the reason why the remaining Reader threads only see a setting (not two) of such variable.
warning I feel this example is a bit contrived to be in the exam. Just remember to place wait in a loop.
[ May 05, 2003: Message edited by: Jose Botella ]
Rory French
Ranch Hand

Joined: Apr 03, 2003
Posts: 97
Hi all
I've studied this thread and worked through Vidya's example and Jose's examples and I think I have understood them. However, I am still concerned about this issue about waiting threads that "spuriously" wake up. I took the example from the Sierra/Bates book (listed in Vidya's first posting in this thread), and completely removed the call to notifyAll(), and still, sometimes, got the same output i.e. all threads ran to completion; none were left waiting.
So I have two questions:
1. Does a waiting thread (i.e. a thread that has called wait() on a particular object) require a notify()/notifyAll() call to reenter the runnable state?
2. Does the omission of any calls to notify()/notifyAll() render the behaviour of a waiting thread unpredictable? (meaning we cannot determin whether a thread will or won't leave the waiting state if the object being waited upon does not make a call to notify()/notifyAll())
These issues are beginning to confuse me, so any light shed on what is or is not guaranteed/predictable behaviour would be much appreciated.
[ May 05, 2003: Message edited by: Rory French ]
Roger Chung-Wee
Ranch Hand

Joined: Sep 29, 2002
Posts: 1683
A sleeping or waiting thread (let's call it T) is in the Not-Runnable state. If the interrupt method is invoked on T from another thread, then T will move out of the Not-Runnable state. When it reaches the running state it will throw an InterruptedException and the interrupt status flag will be cleared.
If the wait method has a timeout of greater than 0 (say 10), then T will wait for at least 10 milliseconds if notify, notifyAll or interrupt are not invoked.
[ May 05, 2003: Message edited by: Roger Chung-Wee ]

SCJP 1.4, SCWCD 1.3, SCBCD 1.3
Giselle Dazzi
Ranch Hand

Joined: Apr 20, 2003
Posts: 168
Hi all, I have a beginner's question about this example, Im just starting to study threads and Im still on the basics:
How does the Reader run() method ever execute if all the start calls are made either to the calculator object or passing the calculator object as the target ?
thx
giselle
[ May 05, 2003: Message edited by: Giselle Dazzi ]

Giselle Dazzi<br />SCJP 1.4
Vidya Ram
Ranch Hand

Joined: Apr 22, 2003
Posts: 62
Gisselle,
"new Reader(calculator).start()" is not passing the calculator object as the target but its invoking the Reader's start() on a new Reader object. The Reader class has a constructor which takes the Calculator object as the argument.
Hope its clear now.
Giselle Dazzi
Ranch Hand

Joined: Apr 20, 2003
Posts: 168
Oops, thx.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: notify() and notifyAll()