为什么wait, notify 和 notifyAll这些方法不在thread类里面?
1 个回答
能治愈生活的良方,是保持对生活的热爱。周维清在 Java 中,`wait()`, `notify()`, 和 `notifyAll()` 方法是用于线程间通信和协作的关键方法。这些方法定义在 `Object` 类中,而不是 `Thread` 类中,这是因为 Java 提供的锁是对象级的,而不是线程级的。 #### 具体原因 1. **锁是对象级的**: - 在 Java 中,每个对象都有一个关联的锁(或监视器),线程通过这个锁来进行同步操作。 - 如果线程需要等待某个锁,它应该调用持有该锁的对象的 `wait()` 方法,这样线程会在该对象上等待,直到其他线程通知它继续执行。 2. **线程等待对象的锁**: - 如果 `wait()` 方法定义在 `Thread` 类中,那么线程正在等待哪个锁将变得不明显,因为线程可以与多个对象相关联。 - 将 `wait()` 定义在 `Object` 类中,可以明确地表示线程正在等待该对象的锁。 3. **线程间通信和协作**: - `wait()`, `notify()`, 和 `notifyAll()` 方法是用于线程间通信和协作的操作。 - 这些方法的调用应该在同步块(即 `synchronized` 块)内部,因为它们需要持有对象的锁才能操作。 - 定义在 `Object` 类中,使得在任意对象上进行同步和通信成为可能。 #### 示例代码 以下是一个简单的例子,演示了 `wait()` 和 `notify()` 的用法: ```java class SharedResource { public synchronized void waitForNotification() { try { System.out.println(Thread.currentThread().getName() + " is waiting."); wait(); System.out.println(Thread.currentThread().getName() + " is notified."); } catch (InterruptedException e) { e.printStackTrace(); } } public synchronized void sendNotification() { System.out.println(Thread.currentThread().getName() + " is notifying."); notify(); } } public class WaitNotifyExample { public static void main(String[] args) { SharedResource sharedResource = new SharedResource(); Thread thread1 = new Thread(() -> { sharedResource.waitForNotification(); }); Thread thread2 = new Thread(() -> { try { Thread.sleep(1000); sharedResource.sendNotification(); } catch (InterruptedException e) { e.printStackTrace(); } }); thread1.start(); thread2.start(); } } ``` ### 关键点总结 - **对象级锁**:Java 提供的锁是对象级的,每个对象都有一个关联的锁。 - **明确等待的锁**:将 `wait()` 方法定义在 `Object` 类中,可以明确线程等待的锁是哪个对象的锁。 - **同步操作**:`wait()`, `notify()`, 和 `notifyAll()` 方法需要在同步块内部调用,确保线程持有对象的锁。 ### 总结 由于 `wait`, `notify`, 和 `notifyAll` 都是锁级别的操作,而锁属于对象,因此将这些方法定义在 `Object` 类中,而不是 `Thread` 类中。这种设计使得线程间的通信和协作更加清晰和有效。发布于 2024-07-24 15:09 •IP属地 云南举报评论收藏
公众号进入网站体验更佳

