TimurVI Asked:2020-02-08 00:07:09 +0800 CST2020-02-08 00:07:09 +0800 CST 2020-02-08 00:07:09 +0800 CST 为什么从同步块或方法中调用 Java 中的 wait/notify/notifyAll 方法? 772 为什么从同步块或方法wait/notify/notifyAll中调用方法?Java java 2 个回答 Voted Best Answer Uraty 2020-02-08T00:27:06+08:002020-02-08T00:27:06+08:00 同步部分指定在调用 notify 时哪些线程将退出等待。那是: class A { synchronized void a() { notify(); // #1 wait(); // #2 } } class B { synchronized void b() { notify(); // #3 wait(); // #4 } } 从 #3 调用 notify 将唤醒从 #4 处于等待状态的线程。但不是#2。对于不同的对象也是如此。现在,如果你这样做 class C { static Object lock = new Integer(); } class A { void a() { synchronized(C.lock) { notify(); // #1 wait(); // #2 } } } class B { void b() { synchronized(C.lock) { notify(); // #3 wait(); // #4 } } } 现在,当从 #3 调用 notify 时,在 #4 和 #2 上休眠的线程都可以唤醒。 Sergey Gornostaev 2020-02-08T00:29:06+08:002020-02-08T00:29:06+08:00 对象的内在锁和它的内在条件队列是相关的:为了调用对象 X 上的任何条件队列方法,您必须持有 X 上的锁。这是因为等待基于状态的条件的机制必然是紧密绑定的保持状态一致性的机制:除非您可以检查状态,否则您不能等待条件,并且除非您可以修改状态,否则您不能从条件等待中释放另一个线程。 © Brian Goetz “Java 并发实践” 在同步块之外,您无法保证不同线程中发生的事件顺序。此外,一个线程可能永远不会知道另一个线程已经改变了任何状态。
同步部分指定在调用 notify 时哪些线程将退出等待。那是:
从 #3 调用 notify 将唤醒从 #4 处于等待状态的线程。但不是#2。对于不同的对象也是如此。现在,如果你这样做
现在,当从 #3 调用 notify 时,在 #4 和 #2 上休眠的线程都可以唤醒。
© Brian Goetz “Java 并发实践”
在同步块之外,您无法保证不同线程中发生的事件顺序。此外,一个线程可能永远不会知道另一个线程已经改变了任何状态。