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 sleep Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Threads and Synchronization
Bookmark "wait and sleep" Watch "wait and sleep" New topic
Author

wait and sleep

Leandro Oliveira
Ranch Hand

Joined: Nov 07, 2002
Posts: 298
what is the difference in using wait and sleep???
for example:
have a class:
class x {
boolean ok=false;
public synchronized void enable(){
ok=true;
notifyAll();
}
public synchronized void produce(){
while(!ok){
wait();
}
//produce
/*
why do i need this loop???why couldn't it be just an if??? if after calling wait on a thread this thread will be ready only if:
----------------- from sun-----------------
Some other thread invokes the notify method for this object and thread T happens to be arbitrarily chosen as the thread to be awakened.
Some other thread invokes the notifyAll method for this object.
Some other thread interrupts thread T.
The specified amount of real time has elapsed, more or less. If timeout is zero, however, then real time is not taken into consideration and the thread simply waits until notified.
--------------------------------------------------
*/
}
}
Michael Morris
Ranch Hand

Joined: Jan 30, 2002
Posts: 3451
Hi leandro,
The differenc between Object.wait() and Thread.sleep() is that the latter is a busy wait and the former is a non-busy wait. First off, the sleep() method is static. It causes all threads to stop execution until it returns. On the other hand, the wait() method tells only the currently executing thread to cease and go into the wait pool until notified by the thread scheduler. That happens when another thread calls notify() or notifyAll() on the same Object. Of course our waiting thread may have to continue to wait if there are other threads in the pool when notifyAll() is called since the scheduler ranodmly chooses a thread to begin execution.
Hope this clears it up,
Michael Morris


Any intelligent fool can make things bigger, more complex, and more violent. It takes a touch of genius - and a lot of courage - to move in the opposite direction. - Ernst F. Schumacher
Leandro Oliveira
Ranch Hand

Joined: Nov 07, 2002
Posts: 298
ok!!!but what about using an if instead of while to make the thread wait???
do{
wait();
}while(!ok);
why I can't use :
if(!ok)
wait();

for what I understood, if a thread attempts to execute this code, it will wait if ok==false, than frees the lock, then another thread will get the lock, if ok==false this current thread will wait and then things go!!! after some while, Thread X calls the enable method, variable ok becomes true, notifyAll is called and then all threads will be ready!!! for what i understood there is no problems in using an if instead of a while!!! But there is some difference!!!
Michael Morris
Ranch Hand

Joined: Jan 30, 2002
Posts: 3451
Hi leandro,
In the case of the if(!ok) then wait() will never be called if ok is true in which case, the thread will finish the method and never go into a wait state. In the do loop wait() will be repeatedly called until ok is true. The implication of that is that until that condition occurs, the thread will remain waiting no matter how many times notify() or notifyAll() is called. Which construct you choose depends on what you are trying to accomplish.
Hope this helps,
Michael Morris
Leandro Oliveira
Ranch Hand

Joined: Nov 07, 2002
Posts: 298
Thank you all!!! I' ve been studing only threads today (better, the last day). And I found what I was looking for!!! you did help me a lot!!! I'm placing here my conclusions!!! Please correct me if I'm wrong.

Conclusions:
you don't need to use a loop. You can use an if like the following:
if(!ok)
wait();
// then the rest of the code that does something
the difference in using an if and a while is in the notify. The wait method does not reset the pc register, the one of the instructions in memory. This register will keep it's value. When a thread call notify, it releases the lock, and only one thread will be requested for entering the 'room'. But the execution of the notifyAll() will make every body alive, one of this threads will get the lock, the others, will wait!! Yes everybody will wake and then only one will get the lock. This one will release the lock when it's done, after that the others threads, the ones that woke up with the call to notifyAll() and then went to wait, they will be notified (after the release of the lock), Since their pc register isn't restarted they won't check, in the if, to see if they are able to go on!!! each of them will get a lock on the object or class, acomplish it's tasks and release to the other!!!
try the following in a class, you will see that it works perfectly!!! than replace the notify with notifyAll(), you will see that things change, it will look like wait does not work well, but the real fact is that the pc register for the threads that call wait are not reset!!!
------------------------
boolean enabled;
public synchronized void enableResource(){
System.out.println(">> enableResource <<");
enabled=true;
this.notify();
}
public synchronized void display(String message){
System.out.println(">> display <<");
if(!enabled){
try{
this.wait();
}catch(Exception e){}
}
------------------------------------------------
This is my conclusion for my doubts!!!
hope I'm rigth and every body who's willing to know, get your problems solved!!!
Greg Charles
Sheriff

Joined: Oct 01, 2001
Posts: 2771
    
  10

I just want to clear up a couple points. First, Thread.sleep() is a static method, but that does not mean it causes every thread to go to sleep as Mr. Morris has claimed. It causes only the current thread to sleep.
The use of a while loop for wait() is generally a good practice. As you pointed out, it is very important when you are using notifyAll() rather than notify(). Of course the program counter doesn't back up to before the if statement when the thread is notified. That would make it a loop, and if you want a loop, just write one. Personally, I always use notifyAll() instead of notify(). My sense is that method works better to prevent starvation and deadlocks, but I can't really explain why I think that.
Peter den Haan
author
Ranch Hand

Joined: Apr 20, 2000
Posts: 3252
Originally posted by Greg Charles:
The use of a while loop for wait() is generally a good practice. [...] Personally, I always use notifyAll() instead of notify(). My sense is that method works better to prevent starvation and deadlocks, but I can't really explain why I think that.
As you mention, the use of if() or while() is actually related to the use of notify() vs notifyAll(). Maybe I can help clarify matters.
You use notify() when the waiting threads are all interchangeable. Because if and only if they are fully interchangeable you don't care which specific thread gets woken up. They can all do the job. A good example would be a thread pool; one or more Threads which wait() until a Runnable job is posted in a job queue. Every single one of the waiting Threads will be able to handle your job, so you can simply call notify() and be sure that the job gets done.
You use an if(condition) as opposed to a while(condition) loop when after notification the wait condition is guaranteed to be met. This can only be the case when the waiting threads are all interchangeable. Imagine a thread pool with a single worker thread. When it's woken up, you know that this is because a job has been posted to the queue:Why bother with the if()? Because if notify() has been called while the thread was busy, the notify will be "lost". By picking up any waiting jobs that are in the queue, such jobs will still be processed.
Do not assume that above statement is true the other way around -- the fact that all waiting threads are interchangeable does not automatically mean you can use if() instead of while(). For example, things get subtly different when there are multiple threads all consuming jobs from the same queue. They are interchangeable, so you can still use notify(), but there is no longer any guarantee that the wait condition will be met when a thread wakes up.I will leave the reason why as an exercise for the reader. Hint: it involves a race condition between a woken-up waiting thread and another thread that has just finished executing its job.
You use notifyAll() when waiting threads are not interchangeable. If some of the waiting threads are able to handle the condition, but others aren't, then you have no choice but to wake up all of them. Imagine, for example, that you want to limit the queue size in the thread pool; this means that a thread that posts new jobs may have to wait() until there is room in the queue. This means you suddenly have two flavours of waiting threads: job posters, and job runners. A call to notify() when there's a free place in the queue may wake up either a poster or a runner. That's useless. You specifically want a poster; the only way to achieve this is to wake up everyone and have every thread check its condition. Which seamlessly leads us into...
You use a while(condition) loop when there is no guarantee that after notification the condition is met. This is generally the case when the waiting threads are not interchangeable. In the example, a notify may mean that there's a job waiting to be run or, conversely, that there's a free place in the queue to post a job to. And since you're forced to wake up all waiting threads, multiple runners will compete for a single job and only one will get it. So all will need to check their wait condition:So what should you use? notify() or notifyAll()? An if() or a wait()? I am personally strongly in favour of not using a single method to cover all situations. Your implementation sends a message to the reader of your code. If you use a while(condition) loop, he will understand that when a thread is woken up the wait condition may not be met --- and if you do this in a situation where, in fact, it is always met you will have confused the reader with misleading code. Made your code that little bit less maintainable.
Hope this helps.
- Peter
[ February 07, 2003: Message edited by: Peter den Haan ]
Peter den Haan
author
Ranch Hand

Joined: Apr 20, 2000
Posts: 3252
I should probably add that my thread pool example also illustrates that choosing between an if() and a while() can be extremely subtle, so in case of doubt simply use while(). There is no excuse for using notifyAll() when a notify() would've done the job, however.
- Peter
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: wait and sleep
 
Similar Threads
wait and notify doubt
A question abt wait() thats matters a lot for timeout
A few questions on wait(), sleep(int) and InterruptedException
Unexpected thread behavior
difference between wait and sleep?