Java 在哪里调用wait()
在我的java程序中,当我编写代码时Java 在哪里调用wait(),java,multithreading,Java,Multithreading,在我的java程序中,当我编写代码时 synchronized(a){ a = 55; a.wait(); } 它在a.wait()上给出运行时异常java.lang.IllegalMonitorStateException语句。但是a=55运行成功 但如果我编码为 synchronized(a){ a.wait(); a = 55; } 然后,它毫无例外地完美运行。为什么会这样?因为a在重新分配后指向不同的对象,并且没有在上同步 换句话说,有两个对象,val
synchronized(a){
a = 55;
a.wait();
}
它在a.wait()上给出运行时异常java.lang.IllegalMonitorStateException
代码>语句。但是a=55
运行成功
但如果我编码为
synchronized(a){
a.wait();
a = 55;
}
然后,它毫无例外地完美运行。为什么会这样?因为a
在重新分配后指向不同的对象,并且没有在上同步
换句话说,有两个对象,val1
和val2
都被分配给变量a
。在val1
上进行同步,但在第一个示例中,调用wait onval2
。您使用的监视器附着到对象,而不是其变量
因此,应该通过引用非最终变量来避免同步。这会导致你的困惑。如果字段是可变的,请使用另一个锁,例如:
Object aMonitor = new Object();
synchronized(aMonitor) {
a = 55;
aMonitor.wait();
}
理想情况下,您的场景只是为了学习wait()
和notify()
是原语,除非作为练习或用于构建自己的并发库,否则不应使用它们。如果是针对真实代码,请在中使用更高级别的机制。,因为a
在重新分配后指向不同的对象,并且未在上同步
换句话说,有两个对象,val1
和val2
都被分配给变量a
。在val1
上进行同步,但在第一个示例中,调用wait onval2
。您使用的监视器附着到对象,而不是其变量
因此,应该通过引用非最终变量来避免同步。这会导致你的困惑。如果字段是可变的,请使用另一个锁,例如:
Object aMonitor = new Object();
synchronized(aMonitor) {
a = 55;
aMonitor.wait();
}
理想情况下,您的场景只是为了学习wait()
和notify()
是原语,除非作为练习或用于构建自己的并发库,否则不应使用它们。如果是真实代码,请在中使用更高级别的机制。,因为您在执行分配时已替换对象a
。这就是所谓的自动装箱a=55
实际上创建了一个新的Integer
对象,因此当您对其调用a.wait()
时,它正在等待您尚未同步的另一个对象,这就是为什么会出现异常
正如我在对的回答中提到的,您不能在synchronized
块内指定对象。即使下面的模式也是一个坏主意,因为当您将a
分配给不同的对象时,这意味着调用synchronized
的下一个线程将在不同的a
上执行,因此两个线程可以同时在同一synchronized
块中
synchronized(a){
a.wait();
// still a bad idea
a = 55;
}
因为您在执行分配时已替换对象a
。这就是所谓的自动装箱a=55
实际上创建了一个新的Integer
对象,因此当您对其调用a.wait()
时,它正在等待您尚未同步的另一个对象,这就是为什么会出现异常
正如我在对的回答中提到的,您不能在synchronized
块内指定对象。即使下面的模式也是一个坏主意,因为当您将a
分配给不同的对象时,这意味着调用synchronized
的下一个线程将在不同的a
上执行,因此两个线程可以同时在同一synchronized
块中
synchronized(a){
a.wait();
// still a bad idea
a = 55;
}
在第一种情况下,变量a(分配给新整数后)不是已同步(a)锁定的“a”,因此调用.wait()会导致异常。在第一种情况下,变量a(分配给新整数后)不是已同步(a)锁定的“a”,因此调用.wait()会导致异常