sleep是Thread静态方法,不释放锁,用于时间控制;wait是Object实例方法,必须在synchronized中调用并释放锁,用于线程协作通信。

Java 中 sleep 和 wait 都能让线程暂停执行,但本质完全不同——不是“相似功能的两个选项”,而是为解决两类问题而设计的机制:一个是时间控制,一个是协作通信。
所属类与调用方式不同
sleep 是 Thread 的静态方法,直接通过 Thread.sleep(millis) 调用,作用对象永远是当前正在运行的线程。它不依赖任何对象实例,也不需要同步上下文。
wait 是 Object 的实例方法,必须通过某个对象调用,如 obj.wait()。它只能在已经获得该对象锁的前提下使用,也就是必须出现在 synchronized(obj) { ... } 块或同步方法中;否则抛出 IllegalMonitorStateException。
锁的行为截然相反
这是最易出错、也最关键的区别:
立即学习“Java免费学习笔记(深入)”;
-
sleep不释放任何锁。即使在 synchronized 块里调用,线程仍牢牢持有对象锁,其他线程无法进入同一同步块。 -
wait必须释放当前对象锁。调用后线程进入对象的等待队列,锁被让出,其他线程可立即获取该锁并执行同步代码。
简单记:sleep 是“抱着锁睡觉”,wait 是“交出锁再等待”。
唤醒机制与使用意图不同
sleep 是单向计时器:指定毫秒数后自动恢复,无需外部干预。适合模拟延迟、限流、轮询间隔等场景。
wait 是协作信号灯:没有 notify 或 notifyAll 就不会醒来(除非设了超时参数)。它服务于条件等待,比如“等队列不为空再消费”“等缓冲区有空位再生产”。
注意:wait() 可能发生虚假唤醒,所以必须配合 while 循环检查条件,不能用 if。
异常与中断响应一致
两者都声明抛出 InterruptedException,调用方必须处理该异常(捕获或向上声明)。线程在休眠或等待过程中收到 interrupt(),都会提前退出并抛出此异常。
但行为略有差异:
– sleep 被中断后,清除中断状态(即 Thread.interrupted() 返回 true 后会重置);
– wait 被中断后,同样抛异常,且中断状态也会被清除。


















