Interview question: sleep VS wait

Purpose

It is convenient for you to review the follow-up interview

resource

A learning video about high-frequency interview questions at Station B

sleep VS wait

common ground

The effects of wait(), wait(long) and sleep(long) are to let the current thread give up the right to use the CPU and enter the blocking state

difference

Method attribution is different

① speep(long) is a static method of Thread
② wait(), wait(long) are member methods of Object, each object has

Wake up at different times

① Threads that execute sleep(long) and wait(long) will wake up after waiting for the corresponding milliseconds.
② wait(long) and wait(long) can also be woken up by notify. If wait() does not wake up, it will wait forever.
③ They can be interrupted

Different lock characteristics

① The call of the wait method must first obtain the lock of the wait object, but sleep has no such restriction
② The object lock will be released after the wait method is executed, allowing other threads to obtain the object lock (I give up, but you can still use it)
③ If sleep is in Executing in a synchronized code block will not release the object lock (I give up, you can't use it)

self test program

/**
 * 面试题: wait和sleep
 *
 * @author xiaozhengN [email protected]
 * @since 2022-10-23 10:25:28
 **/
@Slf4j
public class WaitVsSleep {
    
    

    static final Object LOCK = new Object();

    public static void main(String[] args) throws InterruptedException {
    
    
        // wait 必须配合锁一起使用
        illegalWait();
        waitting();
        sleeping(false);
        sleeping(true);
    }

    private static void sleeping(Boolean isInterrupted) throws InterruptedException {
    
    
        log.info("test sleeping() start, param is {}", isInterrupted);
        Thread t1 = new Thread(() -> {
    
    
            synchronized (LOCK) {
    
    
                try {
    
    
                    log.info("current thread: {} sleeping...", Thread.currentThread().getName());
                    // Thread.sleep() 会继续持有 LOCK 对象的锁资源, 直到自己的事情做完(5s)
                    Thread.sleep(5000L);
                    log.info("current thread: {} sleeping end...", Thread.currentThread().getName());
                } catch (InterruptedException e) {
    
    
                    log.info("current thread: {} has interrupted...", Thread.currentThread().getName(), e);
                }
            }
        }, "T1");
        t1.start();
        Thread.sleep(100);
        if (isInterrupted) {
    
    
            t1.interrupt();
        }
        synchronized (LOCK) {
    
    
            log.info("current thread: {} other...", Thread.currentThread().getName());
        }
        log.info("test sleeping() end...");
    }

    private static void waitting() throws InterruptedException {
    
    
        log.info("test waitting() start...");
        new Thread(() -> {
    
    
            synchronized (LOCK) {
    
    
                try {
    
    
                    log.info("current thread: {} waiting...", Thread.currentThread().getName());
                    // wait() 不会去持续 5s 去占有 LOCK 的锁资源
                    LOCK.wait(5000L);
                } catch (InterruptedException e) {
    
    
                    log.info("current thread: {} interrupted...", Thread.currentThread().getName(), e);
                }
            }
        }, "T1").start();
        Thread.sleep(100);
        synchronized (LOCK) {
    
    
            log.info("current thread: {} other...", Thread.currentThread().getName());
        }
        log.info("test waitting() end...");
    }

    private static void illegalWait() throws InterruptedException {
    
    
        try {
    
    
            LOCK.wait();
        } catch (Exception e) {
    
    
            log.error("执行 sleep 异常: ", e);
        }
    }
}

log analysis

// wait() 必须要持有对象的资源, 才可以让对象wait(), 否则: IllegalMonitorStateException
2022-10-23 11:07:27,634 ERROR [main.daily.WaitVsSleep] - 执行 sleep 异常: 
java.lang.IllegalMonitorStateException
	at java.lang.Object.wait(Native Method)
	at java.lang.Object.wait(Object.java:502)
	at main.daily.WaitVsSleep.illegalWait(WaitVsSleep.java:71)
	at main.daily.WaitVsSleep.main(WaitVsSleep.java:18)

// 注意这个时间: wait() 并没有持续独占 LOCK 锁资源 5 秒
2022-10-23 11:07:27,636 INFO [main.daily.WaitVsSleep] - test waitting() start...
2022-10-23 11:07:27,665 INFO [main.daily.WaitVsSleep] - current thread: T1 waiting...
2022-10-23 11:07:27,764 INFO [main.daily.WaitVsSleep] - current thread: main other...
2022-10-23 11:07:27,764 INFO [main.daily.WaitVsSleep] - test waitting() end...

// 不去打断 sleep(), 支持独占锁资源 5s 才释放
2022-10-23 11:12:14,677 INFO [main.daily.WaitVsSleep] - test sleeping() start, param is false
2022-10-23 11:12:14,678 INFO [main.daily.WaitVsSleep] - current thread: T1 sleeping...
2022-10-23 11:12:19,678 INFO [main.daily.WaitVsSleep] - current thread: T1 sleeping end...
2022-10-23 11:12:19,678 INFO [main.daily.WaitVsSleep] - current thread: main other...

// 打断, 直接释放锁资源
2022-10-23 11:12:19,678 INFO [main.daily.WaitVsSleep] - test sleeping() end...
2022-10-23 11:12:19,678 INFO [main.daily.WaitVsSleep] - test sleeping() start, param is true
2022-10-23 11:12:19,678 INFO [main.daily.WaitVsSleep] - current thread: T1 sleeping...
2022-10-23 11:12:19,779 INFO [main.daily.WaitVsSleep] - current thread: T1 has interrupted...
java.lang.InterruptedException: sleep interrupted
	at java.lang.Thread.sleep(Native Method)
	at main.daily.WaitVsSleep.lambda$sleeping$0(WaitVsSleep.java:31)
	at java.lang.Thread.run(Thread.java:745)
2022-10-23 11:12:19,779 INFO [main.daily.WaitVsSleep] - current thread: main other...
2022-10-23 11:12:19,779 INFO [main.daily.WaitVsSleep] - test sleeping() end...

Guess you like

Origin blog.csdn.net/xiaozhengN/article/details/127471475