wait() 会释放对象锁,sleep() 不释放任何锁;wait() 是 object 方法、需在 synchronized 中调用,sleep() 是 thread 静态方法、可任意调用;wait() 需 notify 唤醒,sleep() 到时自动恢复。

在 Java 中,wait() 和 sleep() 都能让线程暂停执行,但它们对监视器锁(monitor lock)的处理方式完全不同:
wait() 会释放当前持有的对象锁
wait() 是 Object 类的方法,必须在同步上下文(即已获得该对象锁)中调用。调用后,当前线程会:
- 立即释放它所持有的该对象的监视器锁
- 进入该对象的等待队列(wait set),处于
WAITING状态 - 直到被其他线程调用
notify()或notifyAll()唤醒,或被中断、超时才可能重新竞争锁
例如:
synchronized (obj) {
System.out.println("持有锁,准备 wait...");
obj.wait(); // ✅ 此时锁被释放,其他线程可进入 synchronized(obj)
System.out.println("wait 返回,重新获取到锁后继续执行");
}
sleep() 不释放任何锁
sleep() 是 Thread 类的静态方法,作用是让**当前线程暂停指定毫秒数**,但它:
- 完全不关心锁 —— 无论是否持有锁,都不会释放
- 线程状态变为
TIMED_WAITING,但依然持有所有已获得的锁 - 时间一到自动恢复运行(无需唤醒),并继续执行后续代码
例如:
synchronized (obj) {
System.out.println("持有锁,准备 sleep...");
Thread.sleep(1000); // ⚠️ 锁依然被持有!其他线程无法进入 synchronized(obj)
System.out.println("sleep 结束,仍持有锁");
}
关键区别总结
-
调用前提不同:wait() 必须在 synchronized 块/方法内调用,否则抛
IllegalMonitorStateException;sleep() 可在任意位置调用 - 锁行为不同:wait() 主动释放锁,sleep() 完全无视锁
- 唤醒机制不同:wait() 需配合 notify/notifyAll 或中断/超时;sleep() 到时自动恢复
- 所属类不同:wait() 属于 Object,面向对象锁;sleep() 属于 Thread,面向线程自身
典型使用场景
- 用
wait()/notify()实现线程间协作(如生产者-消费者模式),依赖锁释放来让对方线程及时进入临界区 - 用
sleep()实现简单延时(如轮询间隔、模拟耗时操作),不涉及线程通信,也不希望影响锁的持有状态
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











