Differences between wait() and sleep() or sleep() and yield() method in Java Thread is one of the very old questions asked in Java interviews. Though both wait and sleep put threads to the waiting state, they are completely different in terms of behavior and use cases.

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 wait() and sleep() in Java

In the last section, we saw what is wait and sleep method and in this section, we will see the differences between wait and sleep method in Java. As I said before apart from waiting they are completely different from each other:

Call on:

  • wait(): Call on an object; the current thread must synchronize on the lock object.
  • sleep(): Call on a Thread; always currently executing thread.

Synchronized:

  • wait(): when synchronized multiple threads access the same Object one by one.
  • sleep(): when synchronized multiple threads wait for sleepover of the sleeping thread.

Hold lock:

  • wait(): release the lock for other objects to have chance to execute.
  • sleep(): keep lock for at least t times if timeout specified or somebody interrupt.

CPU State:

  • wait(): Thread is still in running mode and uses CPU cycles
  • sleep(): Thread does not consume any CPU cycles

Wake-up condition:

  • wait(): until call notify(), notifyAll() from object, the time of wait() means the least waiting time of the thread.
  • sleep(): until at least time expire or call interrupt().

Usage:

  • sleep(): for time-synchronization and;
  • wait(): for multi-thread-synchronization.

To sum up, you normally use sleep() for time-synchronization and wait() for multi-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

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. yield() method doesn’t guarantee that current thread will pause or stop but it guarantee that CPU will be relinquish by current Thread as a result of call to Thread.yield() method in java.

Here is a list of differences between yield() and wait() method in Java, good to remember for Java interviews :

  • First difference between wait() vs yield() method is that, wait() is declared in java.lang.Object class while yield() is declared on java.lang.Thread class.
  • Second difference between wait() and yield() in Java is that wait is overloaded method and has two version of wait(), normal and timed wait() while yield() is not overloaded.
  • Third difference between wait() and yield() is that wait is an instance method while yield() is an static method and work on current thread.
  • Another difference on wait and yield() is that When a Thread call wait() it releases the monitor.
  • Fifth difference between yield() and wait() which is quite important as well is that wait() method must be called from either synchronized block or synchronized method, There is no such requirement for yield() method.
  • Another Java best practice which differentiate wait() and yield() is that, its advised to call wait() method inside loop but yield() is better to be called outside of loop.

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.

Reference

The Disqus comment system is loading ...
If the message does not appear, please check your Disqus configuration.