sleep () 和 wait () 的区别?
sleep()和wait()均是 Java 中用于 “线程暂停” 的方法,但归属类、核心作用、使用场景差异显著:
# 1. 核心区别
| 对比维度 | sleep() | wait() |
|---|---|---|
| 归属类 | Thread类的静态方法(Thread.sleep(long)) | Object类的实例方法(Object.wait(long)) |
| 调用条件 | 无需持有锁(可在任何地方调用) | 必须持有对象锁(需在synchronized块 / 方法中调用) |
| 锁状态 | 不释放锁(暂停期间仍持有锁) | 释放锁(暂停期间释放对象锁,其他线程可竞争锁) |
| 唤醒方式 | 自动唤醒(睡眠时间到)或interrupt()中断 | notify()/notifyAll()唤醒或wait()超时自动唤醒 |
| 异常处理 | 必须捕获InterruptedException | 必须捕获InterruptedException |
| 核心用途 | 线程暂停一段时间(如延迟执行) | 线程间通信(如生产者 - 消费者模型,等待某个条件满足) |
# 2. 示例
// 1. sleep()示例(不释放锁)
class SleepDemo {
public static void main(String[] args) {
new Thread(() -> {
synchronized (SleepDemo.class) {
System.out.println("线程1持有锁,开始sleep");
try {
Thread.sleep(3000); // 睡眠3秒,不释放锁
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("线程1sleep结束,释放锁");
}
}).start();
new Thread(() -> {
synchronized (SleepDemo.class) {
System.out.println("线程2获取锁"); // 需等待线程1sleep结束才执行
}
}).start();
}
}
// 2. wait()示例(释放锁)
class WaitDemo {
private static Object lock = new Object();
public static void main(String[] args) {
new Thread(() -> {
synchronized (lock) {
System.out.println("线程A持有锁,开始wait");
try {
lock.wait(); // 释放锁,等待唤醒
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("线程A被唤醒,继续执行");
}
}).start();
new Thread(() -> {
synchronized (lock) {
System.out.println("线程B获取锁,唤醒线程A");
lock.notify(); // 唤醒线程A
}
}).start();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# 3. 关键注意事项
wait()必须在synchronized块 / 方法中调用,否则抛出IllegalMonitorStateException;sleep()是静态方法,调用时作用于当前线程(如Thread.sleep(1000)是当前线程睡眠,而非指定线程);- 两者被
interrupt()中断时,都会抛出InterruptedException,且线程会立即唤醒。
#
上次更新: 12/30/2025