thread.sleep()使线程进入timed_waiting状态且不释放锁,用于时间控制;wait()使线程进入waiting或timed_waiting状态并释放锁,需在synchronized内调用,用于线程间条件协作。

Java中Thread.sleep()和Object.wait()看似都是“让线程停一下”,但它们在JVM线程状态变化和锁处理上根本不是一回事——核心差异就两点:一个管“时间”,一个管“条件”;一个独占锁睡觉,一个交出锁等待。
线程状态不同:TIMED_WAITING vs WAITING
sleep会让当前线程进入TIMED_WAITING状态,这是有明确倒计时的暂停。时间一到,线程自动回到RUNNABLE队列,无需外部干预。
wait默认让线程进入WAITING状态(无超时)或TIMED_WAITING(带超时),但它不靠时钟驱动恢复,而依赖其他线程对同一对象调用notify()或notifyAll()。没通知,就一直卡在WAITING里。
锁释放行为截然相反
sleep完全无视锁:哪怕你在synchronized块里调它,锁照常攥着不放。别的线程只能干等,直到你睡醒、退出同步块才可能拿到锁。
wait则必须配合锁使用:调用前必须已持有某个对象的监视器锁(即已在synchronized(obj)内),一旦执行,立刻释放该对象的锁,把“坑位”腾出来——其他线程就能趁机进入同一把锁保护的临界区。
调用前提与异常风险
-
Thread.sleep(1000)是静态方法, anywhere 都能写,不检查上下文 -
obj.wait()是实例方法,必须出现在synchronized(obj)块中;否则直接抛IllegalMonitorStateException - 两者都响应中断,被
interrupt()后都会抛InterruptedException并提前退出阻塞
设计意图决定使用边界
sleep适合“我只想歇一秒”,比如轮询间隔、模拟延迟、控制节奏——不涉及协作,纯时间控制。
wait适合“我得等个信号”,比如生产者发现缓冲区满就wait,消费者取走数据后notify;本质是线程间基于共享对象状态的通信机制,锁释放+等待队列+唤醒协作,三者缺一不可。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











