Java中的wait/notify为什么必须与synchronized一起使用?

233 篇文章 ¥59.90 ¥99.00
Java中的wait/notify方法必须与synchronized一起使用,因为它们依赖对象的监视器,确保线程互斥和同步。wait会使线程释放锁进入等待,notify则唤醒等待线程。不正确使用可能导致IllegalMonitorStateException。通过synchronized,可以避免竞态条件,实现有效的线程间通信。此外,Java还有Condition和BlockingQueue等更高级的通信机制。

在Java中,wait/notify是一对用于线程间通信的方法。wait用于使线程等待,而notify用于唤醒等待的线程。然而,这两个方法必须与synchronized关键字一起使用,这是因为synchronized提供了对共享资源的互斥访问,同时也提供了线程间的可见性。

当一个线程调用某个对象的wait方法时,它会释放该对象的锁,并进入等待状态,直到其他线程调用相同对象的notify方法来唤醒它。在等待期间,该线程不会占用CPU资源,因此可以有效地阻塞线程,直到满足特定的条件。

下面是一个简单的示例代码,演示了wait/notify与synchronized的配合使用:

public class WaitNotifyExample {
   
   
    public static void main(String
`wait()` 方法必须在 `synchronized` 中使用,主要有以下几个关键原因: --- ### 1. **确保线程对对象的互斥访问** Java 的 `wait()` 和 `notify()` / `notifyAll()` 是基于对象的**监视器(Monitor)机制**实现的。只有在获取了对象的锁之后,才能安全地进行等待和唤醒操作。 - 如果没有加锁,多个线程同时调用 `wait()` 或 `notify()`,就会出现**竞态条件(Race Condition)**。 - 加锁保证了在同一时刻只有一个线程可以执行 `wait()` 或 `notify()`。 --- ### 2. **防止丢失信号(Missed Signal)** 线程通常是在某个条件不满足时调用 `wait()`,期望其他线程改变状态并调用 `notify()`。如果这两个操作不在同一个锁的保护下,可能会发生以下情况: - 线程 A 判断条件为假,准备调用 `wait()`; - 此时线程 B 执行完修改状态的操作并调用了 `notify()`; - 然后线程 A 才真正进入等待 —— 此时它就错过了通知,可能永远阻塞。 通过将判断条件、`wait()` 和 `notify()` 都放在同一把锁中,可以避免这种“信号丢失”。 ```java synchronized (obj) { while (conditionNotMet) { obj.wait(); // 安全地等待 } } ``` --- ### 3. **原子性地释放锁并挂起线程** 当一个线程调用 `wait()` 时,它会: - **释放持有的对象锁**; - **被挂起**,直到其他线程调用 `notify()` 或 `notifyAll()`; - 在被唤醒后,重新竞争锁,并从 `wait()` 返回。 这个过程必须是原子的,否则无法保证线程安全。只有在 `synchronized` 块中调用 `wait()`,JVM 才能正确地管理锁的释放恢复。 --- ### 示例说明 ```java Object lock = new Object(); // 线程A new Thread(() -> { synchronized (lock) { try { System.out.println("Thread A is waiting"); lock.wait(); // 必须持有锁才能调用 wait() System.out.println("Thread A is resumed"); } catch (InterruptedException e) { e.printStackTrace(); } } }).start(); // 线程B new Thread(() -> { synchronized (lock) { System.out.println("Thread B is notifying"); lock.notify(); // 必须持有锁才能调用 notify() } }).start(); ``` --- ### 总结 | 原因 | 说明 | |------|------| | **互斥访问** | 防止多个线程同时操作共享资源 | | **防止信号丢失** | 确保 `wait()` 和 `notify()` 能正确配对 | | **原子性释放锁** | 保证线程在等待时释放锁,并在唤醒后重新获取 | ---
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值