Java并发编程:sleep()与wait()核心区别详解
文章摘要:本文详细对比了Java并发编程中sleep()和wait()方法的区别。主要差异包括:sleep()是Thread类静态方法,不释放锁;wait()是Object类实例方法,会释放对象锁。sleep()自动唤醒,wait()需notify()/notifyAll()唤醒。wait()必须在同步块中使用,sleep()则无此限制。文章通过代码示例展示了两种方法在独占锁和线程协作场景下的不同
·
今天完成了实验室纳新网站的工作,大体功能都已经完善,也和前端测试过了,费了点时间,而且今天大部分时间在看langchain4j的东西,就简单复习一下八股,等会再复习一下算法题吧
在Java并发编程中,sleep()和wait()都用于暂停线程执行,但它们在设计目的、行为和使用场景上有本质区别。以下是详细对比及示例说明:
核心区别总结
| 特性 | sleep() | wait() |
|---|---|---|
| 所属类 | Thread类的静态方法 |
Object类的实例方法 |
| 锁释放 | ❌ 不释放任何锁 | ✅ 释放对象锁(只释放调用它的对象的锁) |
| 唤醒条件 | 超时结束或被中断(InterruptedException) |
需其他线程调用notify()/notifyAll()或超时 |
| 同步要求 | 无需在同步块中调用 | 必须在synchronized块或方法中使用 |
| 用途 | 单纯暂停当前线程 | 线程间通信(协调多个线程的执行顺序) |
示例代码解析
示例1:sleep()不释放锁(独占锁场景)
public class SleepDemo {
public static void main(String[] args) {
Object lock = new Object();
new Thread(() -> {
synchronized (lock) {
System.out.println("Thread-1: 获得锁,开始sleep(2000)");
try {
Thread.sleep(2000); // 暂停2秒,但不会释放lock锁
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Thread-1: sleep结束,释放锁");
}
}).start();
new Thread(() -> {
synchronized (lock) {
System.out.println("Thread-2: 获得锁"); // 需等待Thread-1释放锁
}
}).start();
}
}
输出结果:
Thread-1: 获得锁,开始sleep(2000)
(等待2秒...)
Thread-1: sleep结束,释放锁
Thread-2: 获得锁
结论:sleep()期间不释放锁,其他线程无法进入同步块。
示例2:wait()释放锁(线程协作场景)
public class WaitDemo {
public static void main(String[] args) throws InterruptedException {
Object lock = new Object();
// 等待线程
new Thread(() -> {
synchronized (lock) {
System.out.println("Thread-1: 获得锁,调用wait()释放锁");
try {
lock.wait(); // 释放lock锁,进入等待状态
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Thread-1: 被唤醒,重新获得锁");
}
}).start();
Thread.sleep(500); // 确保Thread-1先执行
// 唤醒线程
new Thread(() -> {
synchronized (lock) {
System.out.println("Thread-2: 获得锁,执行notify()");
lock.notify(); // 唤醒Thread-1(但需退出同步块才释放锁)
System.out.println("Thread-2: notify()后,仍持有锁2秒");
try {
Thread.sleep(2000); // sleep()不释放锁
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}
}
输出结果:
Thread-1: 获得锁,调用wait()释放锁
Thread-2: 获得锁,执行notify()
Thread-2: notify()后,仍持有锁2秒
(等待2秒...)
Thread-1: 被唤醒,重新获得锁
结论:
wait()立即释放锁,Thread-2得以进入同步块。Thread-2调用notify()后,Thread-1需等待Thread-2退出同步块(释放锁)才能重新获得锁并继续执行。
关键点详解
-
锁释放机制:
sleep():线程暂停但保留所有锁,可能导致其他线程阻塞。wait():释放调用对象的锁,允许其他线程获得锁并执行。
-
唤醒方式:
sleep():超时结束或调用线程的interrupt()方法。wait():需其他线程显式调用notify()/notifyAll(),或超时(若设置了超时时间)。
-
使用约束:
wait()/notify()必须在synchronized代码块中调用,否则抛出IllegalMonitorStateException。sleep()可在任何上下文调用(但需处理InterruptedException)。
-
设计目的:
sleep():用于定时任务(如轮询间隔)、模拟耗时操作。wait():用于线程协作(如生产者-消费者模型),避免忙等待(busy-waiting)。
经典应用场景
sleep():定时任务调度(如每5秒检查一次状态)、模拟网络延迟。wait()/notify():线程间协调(如生产者生产后通知消费者)、条件等待(等待资源就绪)。
重要提示:Java 5+推荐使用
java.util.concurrent包的Condition、CountDownLatch等高级工具替代wait()/notify(),以简化并发控制。
更多推荐


所有评论(0)