高 基础
sleep与wait区别#
一句话答案#
sleep 是 Thread 方法不释放锁,wait 是 Object 方法释放锁且必须在 synchronized 中调用,用途也不同。
核心要点
| 维度 | sleep() | wait() |
|---|---|---|
| 所属类 | Thread | Object |
| 释放锁 | 不释放 | 释放 |
| 使用条件 | 任意位置 | 必须在 synchronized 中 |
| 唤醒方式 | 超时自动/interrupt | notify()/notifyAll()/超时 |
| 用途 | 暂停执行 | 线程间协作通信 |
| 异常 | InterruptedException | InterruptedException |
为什么 wait 必须在 synchronized 中?
- 防止 lost wake-up:如果不加锁,可能在 wait 之前 notify 已经发生
- wait 会原子地释放锁并进入等待队列
面试标准回答:
sleep 让当前线程暂停指定时间,不释放锁;wait 让当前线程等待,释放锁,直到被 notify 唤醒。本质区别在于是否释放锁和是否用于线程通信。
面试回答(2分钟版)
sleep 和 wait 最本质的区别在于是否释放锁和用途不同。sleep 是 Thread 类的静态方法,让当前线程暂停执行指定时间,但不会释放持有的锁,到时间自动恢复,主要用于控制执行节奏。wait 是 Object 类的方法,必须在 synchronized 同步块中调用,调用后线程会释放锁并进入对象的等待队列,需要其他线程调用 notify 或 notifyAll 来唤醒。wait 必须在 synchronized 中调用的原因是防止 lost wake-up 问题:如果不加锁,可能在 wait 之前 notify 就已经发生了,线程会永远等下去。从线程状态角度看,sleep 使线程进入 TIMED_WAITING 状态,不带参数的 wait 使线程进入 WAITING 状态。简单记忆:sleep 是抱着锁睡觉,到点自己醒;wait 是主动放下锁去等通知,把锁让给别人用。
追问与易错
追问方向:
- “wait 为什么必须在 synchronized 中?”→ 防止 lost wake-up 问题:不加锁时 notify 可能在 wait 之前发生导致信号丢失,线程永久等待;wait 需要原子地释放锁并进入等待队列
- “notify 和 notifyAll 的区别?”→ notify 只随机唤醒一个等待线程,可能唤醒错误线程导致信号丢失;notifyAll 唤醒所有等待线程重新竞争锁,更安全但开销更大,生产中推荐 notifyAll
- “Thread.sleep(0) 有什么用?”→ 触发一次线程调度,让当前线程放弃剩余时间片,给同优先级线程执行机会,相当于一次 yield 操作
易错点:
- ❌ 忘记 wait/notify 配对使用
- ❌ sleep(0) 没有意义——可以触发线程调度