Introduction

In this post, we will discuss the difference between wait() and sleep() methods in java. And discuss how to use these two methods.

Difference between wait and sleep

wait() is a native method defined in Object.

1
public final native void wait(long timeout) throws InterruptedException;

So every instance of the class can call this method. wait() can only be called in a synchronized block. It will release the lock put on the object when it is synchronized.

sleep() is a native static class method that defines Thread.

1
public static native void sleep(long millis) throws InterruptedException;

So Thread.sleep() can be called in any case. thread.sleep() will suspend the current thread and will not release any lock resources.

Let’s look at a simple use of wait.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
@Slf4j
public class WaitUsage {

    private static Object LOCK = new Object();

    public static void WaitExample() throws InterruptedException {
        synchronized (LOCK) {
            LOCK.wait(1000);
            log.info("Object '" + LOCK + "' is woken after" +
                    " waiting for 1 second");
        }
    }
}

Looking at the use of sleep again.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
@Slf4j
public class SleepUsage {

    public static void sleepExample() throws InterruptedException {
        Thread.sleep(1000);
        log.info(
                "Thread '" + Thread.currentThread().getName() +
                        "' is woken after sleeping for 1 second");
    }
}

Wake up wait and sleep

The sleep() method comes with a sleep time, after which the Thread will be woken up automatically. Or it can be interrupted by calling the interrupt() method.

In contrast to wait, waking up is a bit more complicated, as we need to call notify() and notifyAll() to wake up the threads waiting on a specific wait object.

notify() selects a thread to wake up based on the thread scheduling mechanism, while notifyAll() wakes up all the waiting threads, which will then re-claim the resource lock.

wait,notity is usually used in producer and consumer situations, let’s see how to use it.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
@Slf4j
public class WaitNotifyUsage {

    private int count =0;

    public void produceMessage() throws InterruptedException {

        while(true) {
            synchronized (this) {
                while (count == 5) {
                    log.info("count == 5 , wait ....") ;
                    wait();
                }
                count++;
                log.info("produce count {}", count);
                notify();
            }
        }
    }

    public void consumeMessage() throws InterruptedException {

        while (true) {
            synchronized (this) {
                while (count == 0) {
                    log.info("count == 0, wait ...") ;
                    wait();
                }
                log.info("consume count {}", count);
                count--;
                notify();
            }
        }
    }
}

See how to call.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
   @Test
    public void testWaitNotifyUsage() throws InterruptedException{
        WaitNotifyUsage waitNotifyUsage=new WaitNotifyUsage();

        ExecutorService executorService=Executors.newFixedThreadPool(4);
        executorService.submit(()-> {
            try {
                waitNotifyUsage.produceMessage();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

        executorService.submit(()-> {
            try {
                waitNotifyUsage.consumeMessage();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

        Thread.sleep(50000);
    }