• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

notify() and notifyAll()

 
Ranch Hand
Posts: 62
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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 ]
 
Ranch Hand
Posts: 48
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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:
 
Ranch Hand
Posts: 2120
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
 
Jose Botella
Ranch Hand
Posts: 2120
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 62
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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 ]
 
Ranch Hand
Posts: 172
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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?
 
Ranch Hand
Posts: 7729
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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 ]
 
Greenhorn
Posts: 18
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 7729
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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
Posts: 7729
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 2120
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 2120
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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 ]
 
Ranch Hand
Posts: 97
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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 ]
 
Ranch Hand
Posts: 1683
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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 ]
 
Ranch Hand
Posts: 168
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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 ]
 
Vidya Ram
Ranch Hand
Posts: 62
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 168
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Oops, thx.
 
reply
    Bookmark Topic Watch Topic
  • New Topic