• Post Reply Bookmark Topic Watch Topic
  • New Topic

call to wait and and subsequent call to notify is not resuming the work

 
Sanjay Mishra
Ranch Hand
Posts: 84
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Why the following code is not printing "after wait".
My understanding is that call to wait() will move
the thread to the pool of waiting threads. Since
there are no threads waiting, this thread should
get access to the CPU again to complete its work.
But this is not happening.
I am sure I am missing some big concept on wait and
notify. Please clear my doubt.
Regards
Sanjay
class thread extends Thread
{
public void run()
{
System.out.println("before wait");
synchronized(this)
{
try
{
wait();
notify();
}
catch(InterruptedException ioe){}
}
System.out.println("after wait");
}
public static void main(String argv[])
{
Thread t= new thread();
t.start();
}
}

 
Rahul Mahindrakar
Ranch Hand
Posts: 1869
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Sanjay ,
It is recommended that you post all your queries in the respective forum to get a proper and faster response.
There are three overloaded version's of wait() in the Object class which are as follows
1 ) void wait() Causes current thread to wait until another thread invokes the notify() method or the notifyAll() method for this object.
2) void wait(long timeout) : Causes current thread to wait until either another thread invokes the notify() method or the notifyAll() method for this object, or a specified amount of time has elapsed.
3) void wait(long timeout, int nanos) Causes current thread to wait until another thread invokes the notify() method or the notifyAll() method for this object, or some other thread interrupts the current thread, or a certain amount of real time has elapsed.
Basically in all the three versions only another thread can wake up the thread that is waiting. The waiting thread cannot issue a notify() or notifyAll() asking itself to wake up as it does not have the execution with itself.
However a thread can be asked to wait for a given time as in the 2 nd and 3rd overloaded cases of wait in which case it waits for the specified period of time and then starts to compete for resources along with other threads.
Thus if you change your code by changing wait() to wait(5000), the thread will wait for 5 seconds before resuming work.
------------------
Regds.
Rahul P. Mahindrakar

[This message has been edited by Rahul Mahindrakar (edited August 31, 2000).]
 
Ajith Kallambella
Sheriff
Posts: 5782
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
For the benefit of thread lovers, I am moving this to the Threads forum.
Ajith
 
Anonymous
Ranch Hand
Posts: 18944
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Sanjay;
Rahul gave a correct answer, but I'll expand on it a little. Your comment preceding your code tells me where your confusion probably is, so here's a brief explanation of the thread states that apply here.
It's useful to think of the life cycle of a thread as it moves through various states. (There seems to be no agreement among the "authorities" regarding thread states. I like to break them down rather finely; other people lump some of them together.) When you first create it, a thread is in the "new" state. When you call <code>start()</code> on it, the thread moves to the "ready" state; now it's eligible to receive processor time at the discretion of the JVM. When the JVM grants the thread access to the CPU, it moves into the "running" state, where it actually executes the code in its <code>run()</code> method. You probably knew this much already; the part that applies here is next.
In your <code>run()</code> method, you call <code>wait()</code>. This moves the thread into the "waiting" state. While here, it cannot execute it's code, and so your call to <code>notify()</code> never happens. There are 3 ways out of the "waiting" state: 1) the wait can expire (yours won't because you didn't specify a time limit), or 2) the object on which the thread is waiting can move it out if some other thread calls notify() or notifyAll() on that object, or 3) the thread can be interrupted. I think #2 is what you're aiming for here. You need another thread to call the <code>notify()</code> or <code>notifyAll()</code> method of your monitor object (the <code>Thread</code> object <code>t</code> itself, since that's what you synchronized on in this case.) Once your thread leaves the "waiting" state, no matter how, it will move to the "contending for lock" state, where it will stay until it obtains the lock on the monitor object (itself, in this case), at which time it will move back to "ready". You might want to draw a picture of this process.
<code>wait()</code> and <code>notify()</code>/<code>notifyAll()</code> are intended for situations where you have multiple threads that must contend for access to the same object. If you just want to use threads to run unrelated tasks in parallel, you don't need these methods.
Well, I tried to be brief. If this isn't enough, then let me know and I'll write a brief (heh, heh) explanation about monitors, locks, and wait sets.
 
Sanjay Mishra
Ranch Hand
Posts: 84
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hello Rahul/Jply
Thank you very much for u'r detailed explanation.
It cleared much of my doubts but still I am little confused.
Would you please modify this code such that the other
thread is able to wake up this waiting thread.
Thanks in advance
Regards
Sanjay
 
Anonymous
Ranch Hand
Posts: 18944
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Sanjay;
Here's an example of two threads in a producer/consumer relationship. There's this tank, you see, and the consumer wants to empty it. Unfortunately, he can't empty it until the producer fills it, and so the tank makes him wait. Try to tease it apart yourself; if you have any questions I'll try to answer them. (Don't worry right now about the call to <code>sleep</code>, that's just there to make absolutely sure the consumer gets the lock first. If it didn't, my contrived example might deadlock.)
<pre><code>
class SimpleSync {
public static void main( String[] args ) {
Tank theMonitor = new Tank();
Thread dependentThread = new Thread( new Consumer( theMonitor ), "consumer" );
Thread providerThread = new Thread( new Producer( theMonitor ), "producer" );
dependentThread.start();
try {
Thread.currentThread().sleep( 100 );
} catch (InterruptedException e) {}
providerThread.start();
}
}
class Consumer implements Runnable {
private Tank tank;
public Consumer( Tank monitor ) {
tank = monitor;
}
public void run() {
tank.empty();
System.out.println( "Consumer.run() exiting - bye!" );
}
}
class Producer implements Runnable {
private Tank tank;
public Producer( Tank monitor ) {
tank = monitor;
}
public void run() {
tank.fill();
System.out.println( "Producer.run() exiting - bye!" );
}
}
class Tank {
private boolean filled = false;
public synchronized void fill() {
System.out.println( Thread.currentThread().getName() + " got the lock." );
filled = true;
notifyAll();
System.out.println( Thread.currentThread().getName() + " filled the tank." );
}
public synchronized void empty() {
System.out.println( Thread.currentThread().getName() + " got the lock." );
while (!filled) {
try {
System.out.println( Thread.currentThread().getName() + " must wait." );
wait();
} catch (InterruptedException e) {}
}
filled = false;
System.out.println( Thread.currentThread().getName() + " emptied the tank." );
}
}
</code></pre>
 
Anonymous
Ranch Hand
Posts: 18944
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Sanjay;
How ya doin' on that? If you've got a handle on the example, I've got an exercise for you: Modify <code>main</code> in <code>SimpleSync</code> to start several producers and consumers.
Now that there's more than one producer, you'll need to modify <code>Tank.fill</code> so that a producer has to wait if the tank is already full. You'll also have to modify <code>Tank.empty</code> so that it notifies the waiting threads after a consumer empties the tank. Once you're done, you should be able to start producers and consumers in any order (and get rid of that ugly call to <code>sleep</code>).
Let me know how it goes.
jply
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!