面试知识库
基础

sleep与wait区别#

一句话答案#

sleep 是 Thread 方法不释放锁,wait 是 Object 方法释放锁且必须在 synchronized 中调用,用途也不同。

核心要点
维度sleep()wait()
所属类ThreadObject
释放锁不释放释放
使用条件任意位置必须在 synchronized 中
唤醒方式超时自动/interruptnotify()/notifyAll()/超时
用途暂停执行线程间协作通信
异常InterruptedExceptionInterruptedException

为什么 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) 没有意义——可以触发线程调度