Java线程中的sleep、wait和block:区别与联系详解
Java多线程中sleep()、wait()和阻塞的区别:1) sleep()是Thread类方法,不释放锁,线程进入TIMED_WAITING状态;2) wait()是Object方法,必须在同步块调用,会释放锁,线程进入WAITING/TIMED_WAITING状态;3) 阻塞(BLOCKED)是被动状态,发生在竞争同步锁失败时。关键区别在于锁的行为和线程状态变化,sleep()持锁休眠,wa
·
在Java多线程编程中,sleep()、wait()和阻塞(Block) 是三个容易混淆的概念。它们都涉及线程的暂停执行,但行为机制和用途截然不同。本文将通过代码示例解析它们的区别与联系。
1. 线程状态回顾
Java线程的生命周期包含以下状态(Thread.State):
- NEW:新建未启动
- RUNNABLE:可运行(包括运行中和就绪)
- BLOCKED:等待监视器锁(同步阻塞)
- WAITING:无限期等待
- TIMED_WAITING:限时等待
- TERMINATED:终止
2. sleep():主动暂停,不释放锁
作用:让当前线程休眠指定时间,不释放锁。 状态:进入TIMED_WAITING。 唤醒条件:时间结束、被中断(InterruptedException)。 示例:
synchronized (lock) {
System.out.println("Thread sleeping for 2s, holds lock");
Thread.sleep(2000); // 休眠时不释放lock
System.out.println("Thread awakes, still holds lock");
}
3. wait():释放锁,等待唤醒
作用:在同步块中释放锁,让线程等待。 状态:WAITING(无参)或TIMED_WAITING(带超时)。 唤醒条件:
- 其他线程调用
notify()/notifyAll() - 超时时间到(若设定了超时)
- 被中断(
InterruptedException)
示例:
synchronized (lock) {
System.out.println("Thread releases lock via wait()");
lock.wait(); // 释放锁,进入等待
System.out.println("Thread re-acquires lock after notify");
}
4. Blocked:竞争锁失败
触发条件:线程试图获取已被其他线程持有的锁。 状态:BLOCKED。 唤醒条件:锁被释放时,系统自动调度竞争。 示例:
// 线程A
synchronized (lock) {
Thread.sleep(3000); // 持有锁3秒
}
// 线程B
synchronized (lock) { // 若线程A未释放锁,线程B在此阻塞(BLOCKED)
System.out.println("Thread B acquired lock");
}
5. 三者的核心区别
| 特性 | sleep() | wait() | Blocked |
|---|---|---|---|
| 所属类 | Thread |
Object |
系统自动触发 |
| 锁行为 | 不释放锁 | 释放锁 | 因未获锁而阻塞 |
| 调用条件 | 任意场景 | 必须在同步块中 | 竞争同步锁失败 |
| 状态 | TIMED_WAITING |
WAITING/TIMED_WAITING |
BLOCKED |
| 唤醒方式 | 超时或中断 | notify()或超时或中断 |
锁可用时由系统分配 |
| 是否需要同步 | 不需要 | 必须在synchronized中 |
是 |
6. 联系与协作
- wait() 与 notify():经典的生产者-消费者模式中,生产者
wait()释放锁,消费者notify()唤醒生产者。 - sleep() 与 锁竞争:若
sleep()的线程持有锁,其他线程会因竞争失败进入BLOCKED状态。 - 中断响应:三者均可被
interrupt()中断,抛出InterruptedException。
协作示例:
public class WaitSleepDemo {
static final Object lock = new Object();
public static void main(String[] args) {
new Thread(() -> {
synchronized (lock) {
try {
System.out.println("Thread1: Waiting for notify...");
lock.wait(); // 释放锁等待
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
new Thread(() -> {
synchronized (lock) {
System.out.println("Thread2: Sleeping 1s (holds lock)");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
lock.notify(); // 唤醒等待线程
System.out.println("Thread2: Notified!");
}
}).start();
}
}
输出:
Thread1: Waiting for notify...
Thread2: Sleeping 1s (holds lock)
Thread2: Notified!
Thread1: Resumed after notify
7. 总结
- 何时用
sleep():需要暂停线程但不影响锁持有(如定时任务)。 - 何时用
wait():需释放锁并等待条件满足(如线程协作)。 - 理解
BLOCKED:这是被动状态,由锁竞争失败触发。
避免混淆的关键:
🔒
sleep()是“抱着锁睡觉”,wait()是“放开锁等人喊醒”,BLOCKED是“抢锁失败等开门”。
掌握这些区别能帮助开发者写出高效、安全的多线程代码,避免死锁和资源竞争问题!
更多推荐


所有评论(0)