2 回答
TA贡献1799条经验 获得超8个赞
wait()
除非当前线程拥有该对象的监视器,否则不能在对象上。要做到这一点,你必须synchronize
坚持:
class Runner implements Runnable{ public void run() { try { synchronized(Main.main) { Main.main.wait(); } } catch (InterruptedException e) {} System.out.println("Runner away!"); }}
同样的规则也适用于notify()
/ notifyAll()
。
该Javadoc文档wait()
提到这一点:
此方法只应由作为此对象监视器所有者的线程调用。有关
抛出:notify
线程可以成为监视器所有者的方式的说明,请参阅方法。
IllegalMonitorStateException
- 如果当前线程不是此对象监视器的所有者。
来自notify()
:
线程以三种方式之一成为对象监视器的所有者:
通过执行该对象的同步实例方法。
通过执行
synchronized
在对象上同步的语句的主体。对于类型的对象
Class
,通过执行该类的同步静态方法。
TA贡献1804条经验 获得超7个赞
你打电话都wait
和notifyAll
不使用synchronized
块。在这两种情况下,调用线程必须拥有您调用方法的监视器上的锁。
从文档notify
(wait
并notifyAll
有类似的文档,但参考notify
最完整的描述):
此方法只应由作为此对象监视器所有者的线程调用。线程以三种方式之一成为对象监视器的所有者:
通过执行该对象的同步实例方法。
通过执行在对象上同步的synchronized语句的主体。
对于Class类型的对象,通过执行该类的同步静态方法。
一次只有一个线程可以拥有对象的监视器。
只有一个线程能够一次实际退出 wait
,notifyAll
因为他们都必须再次获得相同的监视器 - 但是所有线程都会被通知,所以只要第一个线程退出同步块,下一个将获得锁等
添加回答
举报