不释放
关于Java中sleep
和wait
方法对对象锁的影响,综合权威资料整理如下:
一、sleep
方法
-
所属类与作用
sleep
是Thread
类的静态方法,用于让当前线程暂停执行指定时间,期间不占用CPU资源。 -
锁的释放情况
-
不释放对象锁 :
sleep
方法不会释放任何锁,包括对象锁和同步锁。即使线程处于休眠状态,仍持有对象锁,其他线程无法获取该锁。 -
影响 :若线程持有对象锁,其他线程需等待
notify
或notifyAll
操作才能获取锁,但sleep
期间线程不会主动释放锁。
-
二、wait
方法
-
所属类与作用
wait
是Object
类的方法,只能在同步方法或同步块中使用,用于让当前线程放弃对象锁,进入等待池,等待其他线程调用notify
或notifyAll
后重新获取锁。 -
锁的释放情况
-
释放对象锁 :调用
wait
方法会主动释放对象锁,使其他线程有机会获取锁并执行同步代码块。 -
唤醒条件 :其他线程需调用
notify
或notifyAll
方法,等待线程才会从等待池中唤醒并重新竞争锁。
-
三、对比总结
特征 | sleep | wait |
---|---|---|
所属类 | Thread类(静态方法) | Object类(实例方法) |
锁的释放 | 不释放对象锁 | 释放对象锁 |
等待机制 | 固定时间后自动恢复 | 需外部通知(notify/notifyAll) |
使用场景 | 无需同步资源的简单休眠 | 需同步资源的线程间协作 |
四、示例说明
public class LockExample {
private final Object lock = new Object();
public void sleepWithoutLock() {
synchronized (lock) {
try {
Thread.sleep(1000); // 不释放锁
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void waitWithLock() throws InterruptedException {
synchronized (lock) {
lock.wait(); // 释放锁,等待通知
}
}
}
在sleepWithoutLock
方法中,线程持有锁但不会释放,其他线程无法访问同步块;在waitWithLock
方法中,线程释放锁并进入等待状态,其他线程需调用notify
后才能重新获取锁。
五、注意事项
-
sleep
应配合try-catch
块处理InterruptedException
; -
wait
必须在同步代码块或同步方法中使用,否则会抛出IllegalMonitorStateException
; -
notify
和notifyAll
应谨慎使用,避免死锁。