What is the difference between a wait()
and sleep()
in Threads?
Is my understanding that a wait()
-ing Thread is still in runni
I found this post helpful. It puts the difference between Thread.sleep()
, Thread.yield()
, and Object.wait()
in human terms. To quote:
It all eventually makes its way down to the OS’s scheduler, which hands out timeslices to processes and threads.
sleep(n)
says “I’m done with my timeslice, and please don’t give me another one for at least n milliseconds.” The OS doesn’t even try to schedule the sleeping thread until requested time has passed.
yield()
says “I’m done with my timeslice, but I still have work to do.” The OS is free to immediately give the thread another timeslice, or to give some other thread or process the CPU the yielding thread just gave up.
wait()
says “I’m done with my timeslice. Don’t give me another timeslice until someone calls notify().” As withsleep()
, the OS won’t even try to schedule your task unless someone callsnotify()
(or one of a few other wakeup scenarios occurs).Threads also lose the remainder of their timeslice when they perform blocking IO and under a few other circumstances. If a thread works through the entire timeslice, the OS forcibly takes control roughly as if
yield()
had been called, so that other processes can run.You rarely need
yield()
, but if you have a compute-heavy app with logical task boundaries, inserting ayield()
might improve system responsiveness (at the expense of time — context switches, even just to the OS and back, aren’t free). Measure and test against goals you care about, as always.
The methods are used for different things.
Thread.sleep(5000); // Wait until the time has passed.
Object.wait(); // Wait until some other thread tells me to wake up.
Thread.sleep(n) can be interrupted, but Object.wait() must be notified.
It's possible to specify the maximum time to wait: Object.wait(5000)
so it would be possible to use wait
to, er, sleep
but then you have to bother with locks.
Neither of the methods uses the cpu while sleeping/waiting.
The methods are implemented using native code, using similar constructs but not in the same way.
Look for yourself: Is the source code of native methods available? The file /src/share/vm/prims/jvm.cpp
is the starting point...
A wait can be "woken up" by another thread calling notify on the monitor which is being waited on whereas a sleep cannot. Also a wait
(and notify
) must happen in a block synchronized
on the monitor object whereas sleep
does not:
Object mon = ...;
synchronized (mon) {
mon.wait();
}
At this point the currently executing thread waits and releases the monitor. Another thread may do
synchronized (mon) { mon.notify(); }
(on the same mon
object) and the first thread (assuming it is the only thread waiting on the monitor) will wake up.
You can also call notifyAll if more than one thread is waiting on the monitor – this will wake all of them up. However, only one of the threads will be able to grab the monitor (remember that the wait
is in a synchronized
block) and carry on – the others will then be blocked until they can acquire the monitor's lock.
Another point is that you call wait
on Object itself (i.e. you wait on an object's monitor) whereas you call sleep
on Thread.
Yet another point is that you can get spurious wakeups from wait
(i.e. the thread which is waiting resumes for no apparent reason). You should always wait
whilst spinning on some condition as follows:
synchronized {
while (!condition) { mon.wait(); }
}
In simple words, wait is wait Until some other thread invokes you whereas sleep is "dont execute next statement" for some specified period of time.
Moreover sleep is static method in Thread class and it operates on thread, whereas wait() is in Object class and called on an object.
Another point, when you call wait on some object, the thread involved synchronize the object and then waits. :)
There are some difference key notes i conclude after working on wait and sleep, first take a look on sample using wait() and sleep():
Example1: using wait() and sleep():
synchronized(HandObject) {
while(isHandFree() == false) {
/* Hand is still busy on happy coding or something else, please wait */
HandObject.wait();
}
}
/* Get lock ^^, It is my turn, take a cup beer now */
while (beerIsAvailable() == false) {
/* Beer is still coming, not available, Hand still hold glass to get beer,
don't release hand to perform other task */
Thread.sleep(5000);
}
/* Enjoy my beer now ^^ */
drinkBeers();
/* I have drink enough, now hand can continue with other task: continue coding */
setHandFreeState(true);
synchronized(HandObject) {
HandObject.notifyAll();
}
Let clarity some key notes:
you normally use sleep() for time-syncronization and wait() for multi-thread-synchronization.
Please correct me if i'm wrong.
There are a lot of answers here but I couldn't find the semantic distinction mentioned on any.
It's not about the thread itself; both methods are required as they support very different use-cases.
sleep()
sends the Thread to sleep as it was before, it just packs the context and stops executing for a predefined time. So in order to wake it up before the due time, you need to know the Thread reference. This is not a common situation in a multi-threaded environment. It's mostly used for time-synchronization (e.g. wake in exactly 3.5 seconds) and/or hard-coded fairness (just sleep for a while and let others threads work).
wait()
, on the contrary, is a thread (or message) synchronization mechanism that allows you to notify a Thread of which you have no stored reference (nor care). You can think of it as a publish-subscribe pattern (wait
== subscribe and notify()
== publish). Basically using notify() you are sending a message (that might even not be received at all and normally you don't care).
To sum up, you normally use sleep()
for time-syncronization and wait()
for multi-thread-synchronization.
They could be implemented in the same manner in the underlying OS, or not at all (as previous versions of Java had no real multithreading; probably some small VMs doesn't do that either). Don't forget Java runs on a VM, so your code will be transformed in something different according to the VM/OS/HW it runs on.