wait/sleep/park

博客介绍了线程相关方法。wait/notify可实现线程协调和同步,需先获得synchronized同步块;sleep用于限时休眠,使线程进入TIME_WAITING状态;park能让线程进入WAITING状态,且无需事先获得锁。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

wait/notify:线程实现协调和同步功能,需要事先获得synchronized同步块

sleep: 限时休眠,线程进入TIME_WAITING状态

park:线程进入WAITING状态,无需事先获得锁

<think>我们正在讨论Java中Object.wait()和LockSupport.park()在挂起线程的区别。根据用户的问题和之前的回答,我们需要重点突出两者的核心差异。同,我们可以参考提供的引用内容来增强回答的准确性。 核心区别总结如下: 1. **锁的依赖**: - `Object.wait()`:必须在`synchronized`块内使用,调用前必须持有对象的监视器锁,否则会抛出`IllegalMonitorStateException`。调用`wait()`后,会释放锁。 - `LockSupport.park()`:不需要任何锁,可以在任何地方调用。调用`park()`,不会释放当前线程已经持有的锁。 2. **唤醒机制**: - `Object.wait()`:需要其他线程调用同一对象的`notify()`或`notifyAll()`来唤醒。唤醒后,线程需要重新获取锁才能继续执行。 - `LockSupport.park()`:可以通过`LockSupport.unpark(Thread thread)`来唤醒指定线程。而且,`unpark`可以在`park`之前调用,这样后续的`park`调用会立即返回,不会阻塞。 3. **中断行为**: - `Object.wait()`:在等待过程中如果线程被中断,会抛出`InterruptedException`,并且中断状态会被清除。 - `LockSupport.park()`:被中断不会抛出异常,而是直接返回,但会保留中断状态。可以通过`Thread.interrupted()`来检查中断状态。 4. **超控制**: - `Object.wait()`:提供了带超参数的版本,例如`wait(long timeout)`。 - `LockSupport.park()`:也提供了超控制,如`parkNanos(long nanos)`,支持更精确的纳秒级超。 5. **虚假唤醒**: - 两者都可能发生虚假唤醒,因此通常需要在循环中检查条件。对于`wait()`,官方文档明确要求必须在循环中调用。对于`park()`,同样建议在循环中检查条件,因为除了`unpark`调用和中断外,也可能无故返回。 6. **应用场景**: - `Object.wait()`:通常用于多线程之间的条件等待,如生产者-消费者模型,需要配合`synchronized`使用。 - `LockSupport.park()`:常用于构建更高级的同步工具,如`ReentrantLock`、`CountDownLatch`等,因为它提供了更灵活的线程控制。 引用参考: - 引用[1]指出:LockSupport.park()适合底层同步工具开发,而Object.wait()适合条件驱动的协作场景。 - 引用[2]强调:LockSupport不依赖于对象的监视器锁,可以在任何地方阻塞和唤醒线程。 - 引用[3]说明:LockSupport允许先调用unpark再调用park,此park不会阻塞,而wait/notify则不行(先notify再wait会导致wait永久阻塞)。 现在,我们可以按照用户要求的结构化方式组织答案,并生成相关问题。</think>### Java中`Object.wait()`与`LockSupport.park()`挂起线程的区别 #### 1. **锁依赖与调用限制** - **`Object.wait()`** - **必须持有对象监视器锁**(在 `synchronized` 块内调用),否则抛出 `IllegalMonitorStateException`[^1][^2]。 - 调用后**自动释放锁**,允许其他线程竞争该锁。 - 需通过 `notify()`/`notifyAll()` 唤醒,唤醒后需**重新获取锁**才能继续执行。 ```java synchronized (lock) { while (!condition) { lock.wait(); // 释放锁并挂起 } // 唤醒后需重新获取锁 } ``` - **`LockSupport.park()`** - **无需持有任何锁**,可在任意位置调用[^2][^3]。 - **不会释放已持有的锁**(若调用前已加锁)。 - 通过 `LockSupport.unpark(Thread)` **精确唤醒指定线程**。 #### 2. **唤醒机制的核心差异** | **特性** | **`Object.wait()`** | **`LockSupport.park()`** | |------------------|--------------------------------------|--------------------------------------| | **唤醒方式** | 依赖 `notify()`/`notifyAll()` | 依赖 `unpark(Thread)` | | **唤醒精度** | 随机唤醒或唤醒所有(`notifyAll()`) | 可指定唤醒目标线程 | | **提前唤醒支持** | ❌ 不支持 | ✅ 支持:`unpark()` 可在 `park()` 前调用,使后续 `park()` 立即失效[^3] | ```java // LockSupport 允许先unparkpark(不阻塞) Thread t = Thread.currentThread(); new Thread(() -> LockSupport.unpark(t)).start(); // 先unpark Thread.sleep(100); LockSupport.park(); // 立即返回,不阻塞 ``` #### 3. **中断行为** - **`Object.wait()`** - 被中断**抛出 `InterruptedException`**,并**清除中断标志**,需手动处理异常[^1]。 - **`LockSupport.park()`** - 被中断**静默返回**,**不抛出异常**,且**保留中断标志**(需手动检查 `Thread.interrupted()`)[^2]。 - 若中断标志已为 `true`,则 `park()` **立即失效**(不阻塞)。 #### 4. **超控制** - **`Object.wait(long timeout)`** 支持毫秒级超控制,到期自动唤醒。 - **`LockSupport.parkNanos(long nanos)`** 提供纳秒级超控制,精度更高[^2]。 #### 5. **虚假唤醒处理** - **共同点**:两者都可能发生**虚假唤醒**(无显式唤醒线程自行恢复)。 - **解决方案**:都需在**循环中检查条件变量**: ```java // wait() 范式 synchronized (lock) { while (!condition) { // 循环检查条件 lock.wait(); } } // park() 范式 while (!condition) { // 循环检查条件 LockSupport.park(); if (Thread.interrupted()) { // 处理中断 } } ``` #### 6. **应用场景** | **场景** | **推荐方法** | **原因** | |--------------------------|--------------------|--------------------------------------------------------------------------| | **经典线程协作** | `Object.wait()` | 需与 `synchronized` 配合,适合条件等待范式(如生产者-消费者模型)[^1]。 | | **构建底层同步工具** | `LockSupport.park()` | 无锁依赖,精准唤醒,适合实现锁、屏障等(如 `AQS` 底层)[^2][^3]。 | | **避免锁嵌套问题** | `LockSupport.park()` | 不强制释放锁,防止重入死锁。 | | **响应中断的延任务** | `LockSupport.park()` | 中断行为更可控,无需异常处理[^2]。 | --- ### 关键总结 | **维度** | **`wait()`** | **`park()`** | |------------------|---------------------------------------|---------------------------------------| | **锁依赖** | 必须持有锁 | 无依赖 | | **锁释放** | 自动释放 | 不释放 | | **唤醒精度** | 随机/全部唤醒 | 精确唤醒指定线程 | | **中断响应** | 抛异常,清除中断标志 | 静默返回,保留中断标志 | | **适用层级** | 业务层协作 | 底层同步器实现 | > ⚠️ **注意事项**: > - `wait()` 需严格遵循 `synchronized` 调用规范,否则引发异常。 > - `park()` 的 `unpark()` 可预先调用,避免线程阻塞,此特性在 `wait()`/`notify()` 中不存在[^3]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值