hello啊,各位观众姥爷们!!!本baby今天来报道了!哈哈哈哈哈嗝
特性 | sleep() |
wait() |
---|---|---|
所属类 | Thread 类的静态方法 |
Object 类的实例方法 |
锁的释放 | 不释放锁(保持当前线程持有的锁) | 释放锁(让其他线程获取锁) |
调用条件 | 可在任何地方调用 | 必须在 synchronized 同步块或方法中调用 |
唤醒机制 | 时间到自动唤醒 | 需其他线程调用 notify() /notifyAll() |
作用范围 | 控制线程休眠 | 用于线程间通信(协调共享资源访问) |
异常处理 | 需捕获 InterruptedException |
需捕获 InterruptedException |
sleep()
线程调用 sleep()
后进入休眠状态,但不会释放已持有的锁。其他线程无法获取该锁,可能导致阻塞。
synchronized (lock) {
Thread.sleep(1000); // 持有锁休眠,其他线程无法进入同步块
}
wait()
调用 wait()
会立即释放当前对象的锁,允许其他线程获取锁并执行同步代码块。
synchronized (lock) {
lock.wait(); // 释放锁,其他线程可进入同步块
}
sleep()
用于让线程暂停执行一段时间(如定时任务、模拟延迟)。
// 定时任务:每秒执行一次
while (true) {
doTask();
Thread.sleep(1000); // 休眠 1 秒
}
wait()
用于线程间协作,等待某个条件满足(如生产者-消费者模型)。
// 消费者等待队列非空
synchronized (queue) {
while (queue.isEmpty()) {
queue.wait(); // 释放锁,等待生产者通知
}
queue.poll();
}
sleep()
休眠时间结束后自动恢复,或通过 interrupt()
中断休眠(抛出 InterruptedException
)。
wait()
必须由其他线程调用同一对象的 notify()
或 notifyAll()
唤醒,或等待超时(若指定了时间)。
sleep()
示例public class SleepDemo {
public static void main(String[] args) {
new Thread(() -> {
synchronized (SleepDemo.class) {
System.out.println("线程 A 获取锁,开始休眠 3 秒");
try {
Thread.sleep(3000); // 休眠但不释放锁
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("线程 A 唤醒");
}
}).start();
new Thread(() -> {
synchronized (SleepDemo.class) {
System.out.println("线程 B 获取锁");
}
}).start();
}
}
输出:
线程 A 获取锁,开始休眠 3 秒
(等待 3 秒后)
线程 A 唤醒
线程 B 获取锁
现象:线程 B 必须等待线程 A 释放锁后才能执行。
wait()
示例public class WaitDemo {
public static void main(String[] args) {
Object lock = new Object();
new Thread(() -> {
synchronized (lock) {
System.out.println("线程 A 获取锁,并等待");
try {
lock.wait(); // 释放锁
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("线程 A 被唤醒");
}
}).start();
new Thread(() -> {
synchronized (lock) {
System.out.println("线程 B 获取锁,唤醒线程 A");
lock.notify();
}
}).start();
}
}
输出:
线程 A 获取锁,并等待
线程 B 获取锁,唤醒线程 A
线程 A 被唤醒
现象:线程 A 调用
wait()
后释放锁,线程 B 可以获取锁并唤醒线程 A。
为什么 wait()
必须在同步块中调用?
wait()
和 notify()
依赖于对象的监视器锁(Monitor),调用前必须获取锁,否则抛出 IllegalMonitorStateException
。sleep()
是否会释放锁?
sleep()
是线程自身的行为,与锁无关。如何选择 sleep()
和 wait()
?
sleep()
。wait()
+ notify()
。避免死锁:
wait()
后未被唤醒,将永久阻塞。确保逻辑中始终有唤醒机制。sleep()
:单纯让线程休眠,不涉及锁协调,适用于定时任务或延迟操作。wait()
:用于线程间通信,需与 notify()
配合,确保共享资源的安全访问。sleep()
不释放锁,wait()
释放锁。