关键在于调用意图和锁行为:sleep让线程暂停执行且不释放锁,wait让线程等待条件成立并主动释放锁;前者是thread静态方法,后者是object实例方法且必须在synchronized中调用。

关键不在“状态名”,而在调用意图和锁行为。sleep 是让线程暂停执行,wait 是让线程等待条件成立——这个根本差异决定了它们的使用边界。
看方法归属和调用前提
sleep 是 Thread 类的静态方法,直接写 Thread.sleep(1000) 就行,任何地方都能用,不需要加锁。
wait 是 Object 类的实例方法,必须在 synchronized 块或方法里调用,比如 obj.wait();否则运行时抛 IllegalMonitorStateException。
- 想单纯停 2 秒?用 sleep
- 想等“队列不为空”再消费?用 wait(且必须先拿到队列对象的锁)
盯紧锁会不会被释放
这是最易出错的一点:
- sleep 不放锁:线程抱着 synchronized 锁去睡觉,其他线程干等着,可能引发假死或响应延迟
- wait 主动放锁:一调用就释放当前对象的锁,别的线程能立刻进来操作共享资源,等被唤醒后还要重新抢锁才能继续
比如银行转账中模拟网络延迟,用 sleep 没问题;但消费者发现缓冲区空了,就得用 wait 释放锁,让生产者能及时写入。
注意唤醒方式完全不同
sleep 是“定时闹钟”:时间一到自动醒来,不用别人叫。
wait 是“等人喊你”:必须由同一把锁的其他线程调用 notify() 或 notifyAll() 才能退出等待;超时版本(如 wait(5000))只是加了保底机制,不是主要逻辑。
- 别指望 wait 自己到期就干活——它本质是协作信号,不是计时器
- notify() 只唤醒一个,notifyAll() 唤醒所有等待者,选哪个得看业务是否允许多个线程同时处理
异常处理不能省略
两者都可能被中断,都会抛 InterruptedException,而且抛出后会清除线程的中断状态。
正确做法是捕获后通常要重设中断标志,或按需处理:
- sleep 场景下常选择退出循环或清理资源
- wait 场景下建议在 while 循环里检查条件(避免虚假唤醒),中断时同样要退出等待逻辑
不处理中断,可能让线程在不该停的时候卡住,或该停的时候不停。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











