notify()调用的位置是否重要?(Java)

假设我有以下情况:

synchronized void someMethod() { ... try { wait(); }catch(InterruptedException e) { System.out.println("InterruptedException caught"); } ... } 

 synchronized void someOtherMethod() { ... notify(); } 

然后Thread首先访问someMethod ,进入wait ,然后someOtherMethod通知它并返回Runnable状态。 方法中notify()调用的位置是否重要? 即使我将notify()调用放在方法内的不同位置,我也注意到行为没有变化。

当调用notify()时,不应该立即通知Thread吗?

notify()调用在synchronized块中的位置并不重要,因为根据定义,如果您仍在synchronized块中,那么您仍然保持锁定。

当调用notify()时,不应该立即通知线程吗?

是。 调用notify()将其中一个线程(如果有)从等待队列(等待条件)放入阻塞队列(等待锁定)。 这确实会立即发生,但唤醒线程需要先获得锁定才能开始运行。 因此它立即从等待队列中移出,但仍在等待获取锁定。

顺便说一下,我建议把它写成this.wait()this.notify()只是为了明确哪个对象受到影响。

不,同步块中notify()调用的位置无关紧要。

我推荐的风格:

 class SomeClass { synchronized void someMethod() throws InterruptedException{ ... while (! someCondition) { wait(); } ... } synchronized void someOtherMethod() { ... makeConditionValid(); notifyAll(); } } 

注意在wait调用周围使用while循环。 某些JVM可以发出虚假通知 ,因此无法保证在通知线程时,导致其等待的原始条件有效。 此外,在通知线程放弃锁定之前,唤醒线程不会运行; 所以有可能在等待线程执行时该条件再次无效。

这些调用(即Object#waitObject#notify )需要在synchronized块中进行。 由于您的方法是同步的,因此synchronized块的范围包括方法中的所有内容。 因此,定位与它无关。