File APIs for Java Developers
Manipulate DOC, XLS, PPT, PDF and many others from your application.
http://aspose.com/file-tools
The moose likes Threads and Synchronization and the fly likes wait and notify   code Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of The Java EE 7 Tutorial Volume 1 or Volume 2 this week in the Java EE forum
or jQuery UI in Action in the JavaScript forum!
JavaRanch » Java Forums » Java » Threads and Synchronization
Bookmark "wait and notify   code" Watch "wait and notify   code" New topic
Author

wait and notify code

V K Gupta
Ranch Hand

Joined: Aug 07, 2008
Posts: 55
class Thread31 {
public static void main(String [] args) {
ThreadB b = new ThreadB();

Xyz ob = new Xyz(b);
Thread x = new Thread(ob);

b.setName("Run");
b.start();

x.setName("Jack");
x.start();




synchronized(b) {
try {
System.out.println("Waiting for thread b to finish "+ Thread.currentThread().getName() + " ... ");
b.wait();
}
catch(InterruptedException e)
{
System.out.println("Interrupted");
}


System.out.println("Total in main thread " + b.total );
}

} } // end of class

class Xyz implements Runnable {
ThreadB obj;
Xyz(ThreadB ob) {
obj = ob;
}

public void run() {
synchronized(obj) {
try {
System.out.println("Waiting for thread b to finish " + Thread.currentThread().getName() + " ... ");
obj.wait();
}
catch(InterruptedException e)
{
System.out.println("Interrupted");
}


System.out.println("Total in Xyz thread " + obj.total );
}

}
}// end of class

class ThreadB extends Thread {
int total;
public void run() {
synchronized(this) {
System.out.println(Thread.currentThread().getName() + " is started" );
for(int i=0;i<100;i++) {
total= total + i;
}
System.out.println(Thread.currentThread().getName() + " is going to sleep" );
try { sleep(5000); } catch(Exception e) { }
notify();
System.out.println(" AFter notify() " );
}
}
}

Q) In above prgm i am trying to create two thread to wait on one object and when notify is called, than only one of the two waiting thread should get active. but when i run this prgm both of the two waiting threads run.

i bit confuse about this code. can anyone explain, what exactly is going on in this code
Dariusz Kordonski
Ranch Hand

Joined: Jul 11, 2008
Posts: 49
As I saw the code, I would say that it should make the application hang, because there are two threads calling wait() and only one call to notify(), so at least one thread should remain waiting forever... at least one, because there is a chance that notify runs before both calls to wait() (if 'Run' thread started by b instance gets the lock on this object first, it will execute the whole synchronized block, together with sleep() and notify, before main and Jack have a chance to call wait()).

But I run this code on my computer and it executed just as you said - as though the wait() calls were somehow ignored. I even started one additional Xyz-based thread, but it didn't change anything. Frankly speaking, I don't have any idea why. Either we overlook something very obvious, or the wait()/notify() don't behave as specified in the API
[ August 08, 2008: Message edited by: Dariusz Kordonski ]
V K Gupta
Ranch Hand

Joined: Aug 07, 2008
Posts: 55
Thnks 4 reply,

I TRIED BELOW PROGRAM, THREE THREADS WAITING ON SINGLE OBJECT AND NO NOTIFICATION IS USED THIS TIME BUT EVEN THAN, ALL THREE WAITING THREADS GET START RUNNING.........

THIS EXAMPLE IS FROM THE SCJP BOOK.....

class Thread41 extends Thread {
Calculator c;

public Thread41 (Calculator calc) {
c = calc;
}

public void run() {
synchronized(c) {
try {
System.out.println(Thread.currentThread().getName() + " Waiting for calculation ... ");
c.wait();
} catch(InterruptedException e) { }
System.out.println(Thread.currentThread().getName() + " Total is " + c.total);
}
}


public static void main(String []args) {
Calculator calculator = new Calculator();


Thread a = new Thread41(calculator);
a.setName("A");
Thread b = new Thread41(calculator);
b.setName("B");
Thread c = new Thread41(calculator);
c.setName("C");

a.start();
b.start();
c.start();

try { sleep(2000); } catch(InterruptedException e) { System.out.println("Interrupted " ); }
calculator.start();
}
}

class Calculator extends Thread {
int total;
public void run() {
synchronized(this) {
for(int i=0;i<100;i++) {
total = total + i;
}
System.out.println(" no Notify this time");
//notify();
}
}
}

what's going on in this code ?
Norm Radder
Ranch Hand

Joined: Aug 10, 2005
Posts: 685
The API doc says:
A thread can also wake up without being notified, interrupted, or timing out, a so-called spurious
wakeup. While this will rarely occur in practice, applications must guard against it by testing for
the condition that should have caused the thread to be awakened, and continuing to wait if the
condition is not satisfied. In other words, waits should always occur in loops, like this one:
synchronized (obj) {
while (<condition does not hold>
obj.wait(timeout);
... // Perform action appropriate to condition
}

So you need to add code to test if a condition is true.
Seems like wait() is a different kind of yield().
Steve Luke
Bartender

Joined: Jan 28, 2003
Posts: 4181
    
  21

It appears that when a Thread exits a notifyAll() gets called on it, or some equivalent release.

In your first posted application, here are the sequence of events that happen in the Run thread:

"Run" thread's start() method called
"Run" thread added to "main" thread group's running threads
"Run" gets some unknown native voodoo on it :-)
"Run" thread's run() method called
"Run" thread attains lock for the current instance of itself
"Run" does its work
"Run" notify()s one Thread who is blocked waiting on itself
"Run" releases the lock on itself
"Run" gets some unknown native voodoo on it
"Run" thread's exit() method called
"Run" thread is removed from "main" thread group
"Run" thread may have more unknown native voodoo done on it
"Run" thread appears to have notifyAll() called on itself
"Run" thread dies.

Since you are waiting on a Thread, and the Thread gets notifyAll() called on it when its job is done, all listeners wake up and begin to do their work.


Steve
Abhijeet Nalawade
Greenhorn

Joined: Apr 01, 2007
Posts: 20
In above prgm i am trying to create two thread to wait on one object and when notify is called, than only one of the two waiting thread should get active. but when i run this prgm both of the two waiting threads run.


I actually have written a code on similar lines as written by Vijay and it is functioning as expected..But i am not able to figure out the change in Vijay's code in order to function on similar lines.

Steve Luke
Bartender

Joined: Jan 28, 2003
Posts: 4181
    
  21

Originally posted by Abhijeet Nalawade:


I actually have written a code on similar lines as written by Vijay and it is functioning as expected..But i am not able to figure out the change in Vijay's code in order to function on similar lines.


In your code, you are using a Runnable to run the code, and you are synchronizing on the Runnable, not the Thread - which is what Vijay should be doing.

He should change ThreadB to implement Runnable instead of extending Thread, and start it like you start Internal i1.
Dariusz Kordonski
Ranch Hand

Joined: Jul 11, 2008
Posts: 49
You're right Steve. More specifically, the issue arises, if you synchronize on the Thread object (I left the ThradB class extending thread, but refactored the code to synchronize on an instance of a separate class, not ThreadB - the code worked 'as it should' i.e. hanged). Probably bacause, as Steve explained, notifyAll() (or something similar) is called on a Thread object before the corresponding thread dies.
Andrei Matyas
Greenhorn

Joined: Apr 15, 2007
Posts: 25
Hello

When you call wait on a monitor you release the lock on it


A thread that calls wait()
releases the virtual CPU; at the same time, it releases the lock. It enters a pool of waiting threads,
which is managed by the object whose wait() method got called. Every object has such a pool.
...
 
It is sorta covered in the JavaRanch Style Guide.
 
subject: wait and notify code