今天完成了实验室纳新网站的工作,大体功能都已经完善,也和前端测试过了,费了点时间,而且今天大部分时间在看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()
,以简化并发控制。