Interview shock 25: what's the difference between sleep and wait

Both the sleep method and the wait method are used to put the thread into the sleep state, and both the sleep method and the wait method can respond to the interrupt interrupt, that is, if the thread receives the interrupt signal during sleep, it can respond and throw the InterruptedException exception. What are the differences between sleep and wait? Next, let's take a look.

Difference 1: different syntax

The wait method must be used together with synchronized, or an exception of IllegalMonitorStateException will be thrown at runtime, as shown in the following code:

At first glance, the code seems to be OK, and the compiler does not report an error. However, when we run the above program, the following errors will occur:

sleep can be used alone without being used together with synchronized.

Difference 2: different categories

The wait method belongs to the method of Object class, while sleep belongs to the method of Thread class, as shown in the following figure:

Difference 3: different ways of arousal

The sleep method must pass a timeout parameter, and after the timeout, the thread will wake up automatically. The wait method can not pass any parameters. When it does not pass any parameters, it indicates permanent sleep. The dormant thread can not be awakened until another thread calls notify or notifyAll. In other words, the sleep method has the function of active wake-up, and the wait method without passing any parameters can only be awakened passively.

Difference 4: different lock release resources

The wait method will actively release the lock, while the sleep method will not. Next, we use code to demonstrate the difference between the two.

sleep does not release the lock

Next, sleep is used to sleep for 2s, and then try to obtain the public lock in another thread. If the lock can be obtained, sleep will release the lock during sleep, otherwise it will not release the lock. The implementation code is as follows:

public static void main(String[] args) throws InterruptedException {
    Object lock = new Object();
    new Thread(() -> {
        synchronized (lock) {
            System.out.println("Lock acquired by new thread:" + LocalDateTime.now());
            try {
                // Sleep for 2s
                Thread.sleep(2000);
                System.out.println("New thread released lock:" + LocalDateTime.now());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }).start();
    // Wait for the new thread to obtain the lock first
    Thread.sleep(200);
    System.out.println("The main thread attempted to acquire a lock:" + LocalDateTime.now());
    // After a new thread hibernates, an attempt is made to acquire a lock
    synchronized (lock) {
        System.out.println("Lock acquired by main thread:" + LocalDateTime.now());
    }
}

The execution result of the above code is shown in the following figure:

It can be seen from the above results that after calling sleep, the attempt to obtain the lock in the main thread is unsuccessful. Only after the sleep is executed and the lock is released, the main thread can get the lock normally, which indicates that sleep will not release the lock during sleep.

wait release lock

Next, use the same method to replace sleep with wait. After the thread sleeps, try to obtain the lock in another thread. The implementation code is as follows:

public static void main(String[] args) throws InterruptedException {
    Object lock = new Object();
    new Thread(() -> {
        synchronized (lock) {
            System.out.println("Lock acquired by new thread:" + LocalDateTime.now());
            try {
                // Sleep for 2s
                lock.wait(2000);
                System.out.println("New thread released lock:" + LocalDateTime.now());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }).start();
    // Wait for the new thread to obtain the lock first
    Thread.sleep(200);
    System.out.println("The main thread attempted to acquire a lock:" + LocalDateTime.now());
    // After a new thread hibernates, an attempt is made to acquire a lock
    synchronized (lock) {
        System.out.println("Lock acquired by main thread:" + LocalDateTime.now());
    }
}

The execution result of the above code is shown in the following figure:

It can be seen from the above results that after calling wait, the mainline immediately attempts to obtain the lock successfully, which indicates that the lock is released during wait sleep.

Difference 5: different thread entry States

Calling the sleep method, the thread will enter TIMED_WAITING has a time limit WAITING state. When calling the wait method without parameters, the thread will enter the WAITING has no time limit WAITING state.
Code demonstration:

public static void main(String[] args) throws InterruptedException {
    Object lock = new Object();
    Thread t1 = new Thread(() -> {
        synchronized (lock) {
            try {
                // Sleep for 2s
                lock.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    });
    t1.start();

    Thread t2 = new Thread(() -> {
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    });
    t2.start();

    Thread.sleep(200);
    System.out.println("wait() Then enter the state:" + t1.getState());
    System.out.println("sleep(2000) Then enter the state:" + t2.getState());

}

The execution result of the above code is as follows:

summary

Both sleep and wait can put threads into sleep state, and they can respond to interrupt interrupt, but the differences between them are mainly reflected in: different syntax, different classes, different wake-up methods, different lock release and different state of threads.

Right and wrong are judged by ourselves, bad reputation is heard by others, and the number of gains and losses is safe.

The official account: Java interview

Interview collection: https://gitee.com/mydb/interview

Keywords: Java Back-end Interview

Added by sbinkerd1 on Wed, 23 Feb 2022 03:22:55 +0200