wait() 和 sleep()是否会触发锁的释放以及CPU资源的释放?
这是 Java 多线程中常见且非常重要的面试和实践问题。我们来从底层机制角度全面分析:
问题简化版回答:
| 方法 | 是否释放锁(monitor) | 是否释放CPU 资源(即不占用 CPU) |
|---|---|---|
wait() | 是,会释放锁 | 是,线程进入 WAITING 状态,暂停执行 |
sleep() | 否,不释放锁 | 是,线程进入 TIMED_WAITING 状态,暂停执行 |
一、什么是“释放锁”和“释放 CPU”?
- 释放锁(monitor):表示线程暂停运行时,会不会把它持有的对象监视器锁(例如 synchronized)释放给其他线程。
- 释放 CPU:表示线程暂停运行,进入非运行态(RUNNABLE),让出 CPU 时间片。
二、wait() 的行为分析
概述:
wait()是 Object 类的方法,只能在同步块 (synchronized) 中调用。- 当一个线程调用
wait(): - 当前线程会立即 释放锁
- 线程进入 WAITING 状态
- 必须由其他线程通过
notify()或notifyAll()来唤醒
示例:
synchronized (obj) {
obj.wait(); // 线程暂停并释放 obj 的锁
}
状态:
- 等待状态(
WAITING) - 不消耗 CPU,线程暂停运行
- 会释放对象锁,让其他线程可进入同步块
三、sleep() 的行为分析
概述:
sleep()是Thread类的静态方法,不依赖锁- 当前线程暂停一段时间(毫秒/纳秒)
- 不释放锁,即便当前线程在
synchronized块中
示例:
synchronized (obj) {
Thread.sleep(1000); // 不释放 obj 锁,只是不运行
}
状态:
- 计时等待状态(
TIMED_WAITING) - 不消耗 CPU,但仍然持有锁
- 其他线程依然无法获取该锁
四、直观对比图
是否释放锁 是否让出 CPU
wait() 是 是
sleep() 否 是
五、适用场景对比
| 场景 | 推荐方法 | 理由 |
|---|---|---|
| 线程间通信/协调 | wait() | 可释放锁并等待通知,适用于生产者消费者等场景 |
| 简单延迟/定时 | sleep() | 不需要锁操作,只需线程暂停一段时间 |
| 在 synchronized 中暂停线程 | sleep() | 保持锁的场景需要 sleep(),避免逻辑中断 |
六、参考资料
- Java官方文档 – Object.wait()
- Java官方文档 – Thread.sleep()
- 《Java 并发编程实战》 – 第 3 章:线程协调
七、总结回顾
| 方法 | 是否释放锁 | 是否释放 CPU | 主要用途 |
|---|---|---|---|
wait() | 是 | 是 | 线程间协调与通信 |
sleep() | 否 | 是 | 单线程延迟等待,不涉及锁 |
更多详细内容请关注其他相关文章!