面试题:sleep VS wait

目的

方便自己后续面试复习方便

资源

B站的一个讲高频面试题的一个学习视频

sleep VS wait

共同点

wait(), wait(long)和sleep(long)的效果都是让当前线程放弃CPU的使用权, 进入阻塞状态

不同点

方法归属不同

① speep(long)是Thread的静态方法
② wait(), wait(long) 都是Object的成员方法, 每个对象都有

醒来时机不同

① 执行sleep(long)和wait(long)的线程都会在等待相应的毫秒后醒来
② wait(long)和wait(long)还可以被notify唤醒, wait()如果不唤醒就一直等下去
③ 它们都可以被打断唤醒

锁特性不同

① wait方法的调用必须先获取wait对象的锁, 而sleep则无此限制
② wait方法执行后会释放对象锁, 允许其他线程获得该对象锁 (我放弃, 但你们还可以用)
③ sleep如果在synchronized代码块中执行, 并不会释放对象锁 (我放弃, 你们也用不了)

自测试程序

/**
 * 面试题: 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);
        }
    }
}

日志分析

// 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...

猜你喜欢

转载自blog.csdn.net/xiaozhengN/article/details/127471475
今日推荐