Difference between wait() and sleep(), yield() in Java
The difference between wait() and sleep(), or between sleep() and yield(), is one of the oldest questions asked in Java interviews. All three pause the currently running thread, but they differ in who owns them, whether they release the lock, and how the thread wakes up again.
TL;DR
sleep() | yield() | wait() | |
|---|---|---|---|
| Defined in | Thread | Thread | Object |
| Static method? | Yes | Yes | No |
| Releases the lock/monitor? | No | No | Yes |
Must hold the monitor (be in synchronized)? | No | No | Yes |
| Wakes up when | timeout expires or interrupted | the scheduler decides (maybe immediately) | notify()/notifyAll(), timeout, or interrupt |
| Typical use | pause for a fixed time | hint to give up the CPU | coordination between threads |
JavaDoc Definition
Thread Class
public static void sleep(long millis[, int nanos]) throws InterruptedException
Causes the currently executing thread to sleep (temporarily cease execution) for the specified number of milliseconds plus the specified number of nanoseconds, subject to the precision and accuracy of system timers and schedulers. The thread does not lose ownership of any monitors.
Parameters:
millis - the length of time to sleep in milliseconds
nanos - 0-999999 additional nanoseconds to sleep
Throws:
IllegalArgumentException - if the value of millis is negative, or the value of nanos is not in the range 0-999999
InterruptedException - if any thread has interrupted the current thread. The interrupted status of the current thread is cleared when this exception is thrown.
public static void yield()
A hint to the scheduler that the current thread is willing to yield its current use of a processor. The scheduler is free to ignore this hint.
Yield is a heuristic attempt to improve relative progression between threads that would otherwise over-utilize a CPU. Its use should be combined with detailed profiling and benchmarking to ensure that it actually has the desired effect.
It is rarely appropriate to use this method. It may be useful for debugging or testing purposes, where it may help to reproduce bugs due to race conditions. It may also be useful when designing concurrency control constructs such as the ones in the java.util.concurrent.locks package.
Object Class
public final void wait([long timeout[, int nanos]]) throws InterruptedException
Causes the 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.
This method is similar to the wait method of one argument, but it allows finer control over the amount of time to wait for a notification before giving up. The amount of real-time, measured in nanoseconds, is given by:
1000000*timeout+nanos
In all other respects, this method does the same thing as the method wait(long) of one argument. In particular, wait(0, 0) means the same thing as wait(0).
If the timeout was not given, wait() means the same thing as wait(0).
The current thread must own this object’s monitor. The thread releases ownership of this monitor and waits until either of the following two conditions has occurred:
Another thread notifies threads waiting on this object’s monitor to wake up either through a call to the notify method or the notifyAll method.
The timeout period, specified by timeout milliseconds plus nanos nanoseconds arguments, has elapsed.
The thread then waits until it can re-obtain ownership of the monitor and resumes execution.
As in the one argument version, interrupts and spurious wakeups are possible, and this method should always be used in a loop:
synchronized(obj) {
while ( <condition does not hold> ) {
obj.wait(timeout, nanos);
... // Perform action appropriate to condition
}
}
This method should only be called by a thread that is the owner of this object’s monitor. See the notify method for a description of the ways in which a thread can become the owner of a monitor.
Parameters:
timeout - the maximum time to wait in milliseconds.
nanos - additional time, in nanoseconds range 0-999999.
Throws:
IllegalArgumentException - if the value of timeout is negative or the value of nanos is not in the range 0-999999.
IllegalMonitorStateException - if the current thread is not the owner of this object’s monitor.
InterruptedException - if any thread interrupted the current thread before or while the current thread was waiting for a notification. The interrupted status of the current thread is cleared when this exception is thrown.
OS’s Scheduler’s Perspective
.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 the 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 with sleep, the OS won’t even try to schedule your task unless someone calls notify (or one of a few other wakeup scenarios occurs).
Difference between sleep() and wait() in Java
Both put the current thread on hold, but they differ on almost every other axis:
Belongs to:
- sleep(): a static method on
Thread; always acts on the currently executing thread. - wait(): an instance method on
Object; called on the object whose monitor the thread holds.
Lock/monitor:
- sleep(): keeps every monitor the thread holds for the whole duration.
- wait(): releases the monitor of the object, giving other threads a chance to run.
Synchronization requirement:
- sleep(): none; it can be called from anywhere.
- wait(): must be called from inside a
synchronizedblock or method on that object, otherwise it throwsIllegalMonitorStateException.
Wakes up when:
- sleep(): the timeout expires, or the thread is interrupted.
- wait(): another thread calls
notify()/notifyAll()on the object, the optional timeout expires, or the thread is interrupted.
Typical use:
- sleep(): pausing for a known interval (time-based synchronization).
- wait(): coordinating work between threads (inter-thread synchronization).
Example
public class ThreadTest implements Runnable {
private int number = 10;
public void firstMethod() throws Exception {
synchronized(this) {
number += 100;
System.out.println("Number in First Method: " + number);
}
}
public void secondMethod() throws Exception {
synchronized(this) {
Thread.sleep(1000); // (1)
this.wait(1000); // (2)
number *= 200;
System.out.println("Number in Second Method: " + number);
}
}
public void run() {
try {
firstMethod();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) throws Exception {
ThreadTest threadTest = new ThreadTest();
Thread thread = new Thread(threadTest);
thread.start();
threadTest.secondMethod();
}
}
The output with (1): Thread.sleep(1000);
Number in Second Method: 2000
Number in First Method: 2100
The output with (2): this.wait(1000);
Number in First Method: 110
Number in Second Method: 22000
The two outputs come from the same code, and the only thing that changes is whether the lock is held during the pause:
- With
Thread.sleep(1000),secondMethod()keeps the monitor onthreadTestwhile it sleeps. The spawned thread cannot enterfirstMethod()(alsosynchronized(this)) untilsecondMethod()finishes, sosecondMethod()runs first:10 * 200 = 2000, thenfirstMethod()adds 100 to give2100. - With
this.wait(1000),secondMethod()releases the monitor while it waits. The spawned thread immediately entersfirstMethod():10 + 100 = 110. Whenwait()returns and reacquires the monitor,secondMethod()runs:110 * 200 = 22000.
Difference between sleep() and yield() in Java
Both are static methods on Thread that pause the current thread without releasing any lock, but the resemblance ends there:
- Duration: sleep() pauses for a defined period; yield() has no duration and only hints that the thread is willing to step aside.
- Guarantee: sleep() stops the thread for at least the requested time (unless interrupted); yield() guarantees nothing, since the scheduler is free to ignore the hint and resume the thread immediately.
- Interruptible: sleep() throws
InterruptedException; yield() does not. - Typical use: sleep() to wait a known interval; yield() to hint the scheduler inside compute-heavy loops (rarely needed in practice).
Difference between yield() and wait() in Java
yield() method pauses the currently executing thread temporarily for giving a chance to the remaining waiting threads of the same priority to execute. If there is no waiting thread or all the waiting threads have a lower priority then the same thread will continue its execution. The yielded thread when it will get the chance for execution is decided by the thread scheduler whose behavior is vendor dependent. The yield() method doesn’t guarantee that the current thread will pause or stop, but it does guarantee that the CPU will be relinquished by the current thread as a result of the call to Thread.yield() in Java.
Here is a list of differences between yield() and wait(), good to remember for Java interviews:
- Belongs to: wait() is an instance method on
java.lang.Object; yield() is a static method onjava.lang.Thread. - Overloading: wait() is overloaded (a plain version and a timed version); yield() is not.
- Lock/monitor: wait() releases the object’s monitor; yield() releases nothing.
- Synchronization requirement: wait() must be called from a
synchronizedblock or method; yield() has no such requirement. - Loop usage: wait() should be called inside a loop to guard against spurious wakeups; yield() does not need a loop.
- Wakes up when: wait() resumes on
notify()/notifyAll(), timeout, or interrupt; yield() may resume as soon as the scheduler chooses.
You rarely need yield(), but if you have a compute-heavy app with logical task boundaries, inserting a yield 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 Disqus comment system is loading ...
If the message does not appear, please check your Disqus configuration.