sleep方法不释放锁,仅暂停线程执行;wait方法则自动释放锁并需notify唤醒,二者语义与使用场景截然不同。

Java 中 sleep 方法本身**不保障**也不“主动维持”锁——它根本不管锁的事。它的行为是:休眠期间,锁自然留在原线程手里,因为什么都没做去释放它。
sleep 从不触碰锁,所以锁不会丢
Thread.sleep() 是一个纯调度操作:只让当前线程暂停执行、进入 TIMED_WAITING 状态、让出 CPU 时间片。它既不调用 unlock,也不通知 JVM 或监视器(monitor)释放任何锁。
- 如果线程正持有
synchronized(this)锁,调用sleep()后,锁仍被该线程独占,其他线程无法进入同一同步块 - 如果使用
ReentrantLock并已调用lock.lock(),sleep()不会触发unlock(),锁持续被持有 - 这就像人坐着不动打个盹——手还攥着门把手(锁),门依然关着
和 wait 的关键区别就在这里
wait() 是协作式等待,设计上必须配合锁:它在进入等待前自动释放锁,等被唤醒后重新竞争。而 sleep() 没有这种语义。
-
wait()→ 必须在 synchronized 块内;会释放锁;需 notify 唤醒 -
sleep()→ 可在任意位置调用;不释放锁;时间到或被中断即恢复 - 误把
sleep()当wait()用,容易造成其他线程无限阻塞
真正“保障锁不丢”的其实是 JVM 锁机制本身
Java 的 monitor 锁(synchronized)和 AQS 锁(ReentrantLock)都绑定在线程身份上。只要线程没退出同步上下文、没调用 unlock,锁就不会被回收或转移。
立即学习“Java免费学习笔记(深入)”;
- 线程在 synchronized 方法里 sleep → 退出方法时才释放锁
- 线程持 ReentrantLock 后 sleep → 必须显式 unlock 才释放
- JVM 不会因为线程休眠就“没收”它的锁,这是底层线程模型的保证
注意中断处理别破坏锁一致性
sleep() 可被中断,抛出 InterruptedException,此时中断状态会被清空。若在锁保护的逻辑中被中断,需确保异常处理不跳过 unlock 或提前退出。
- 错误:捕获
InterruptedException后直接 return,却忘了 unlock(ReentrantLock 场景) - 正确:在 catch 块中恢复中断状态,并按业务逻辑决定是否释放锁、清理资源
- 示例:先
lock.unlock(),再Thread.currentThread().interrupt()


















