问题描述
在我的Java程序中,当我编写代码时
In my java program, when I code
synchronized(a){
a = 55;
a.wait();
}
它在a.wait();
语句上给出运行时异常java.lang.IllegalMonitorStateException
.但是a=55
运行成功.
It gives run time exception java.lang.IllegalMonitorStateException
on a.wait();
statement. However a=55
runs successfully.
但是如果我编码为
synchronized(a){
a.wait();
a = 55;
}
然后它运行完美,没有任何异常.为什么会这样?
then it runs perfectly without any exception. why so?
推荐答案
因为a
在重新分配后指向另一个对象,并且未同步.
Because a
is pointing to a different object after reassignment, and is not being synchronized on.
换句话说,有两个对象val1
和val2
都分配给变量a
.您在val1
上进行同步,但在第一个示例中,调用在val2
上等待.您使用的监视器将附加到对象,而不是其变量.
In other words, there are two objects, val1
and val2
that are both assigned to the variable a
. You synchronize on val1
but in the first example call wait on val2
. The monitor you use is attached to the object, not its variable.
因此,应避免通过引用非最终变量进行同步.这会导致您的困惑.如果该字段是可变的,请使用另一个锁,例如:
You should thus avoid synchronizing by referencing a non-final variable. This leads to your confusion. If the field is mutable, use another lock, for example:
Object aMonitor = new Object();
synchronized(aMonitor) {
a = 55;
aMonitor.wait();
}
理想情况下,您的方案只是为了学习. wait()
和notify()
是基元,除非用作练习或用于构建自己的并发库,否则不应使用它们.如果用于真实代码,请在 java.util.concurrent
.
Ideally your scenario is just for learning though. wait()
and notify()
are primitives and shouldn't be used unless as an exercise or for building your own concurrency library. If it's for real code, use a higher level mechanism in java.util.concurrent
.
这篇关于在哪里调用wait()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!