我不知道为什么程序出错了,它抛出IllegalMonitorStateException
同步
为什么我无法获得监视器对象??
public class Test extends Thread{
Boolean flag = false ;
@Override
public void run() {
while( true ) {
try {
Thread.sleep(10) ;
}catch (Exception e) {}
}
}
public void change() {
synchronized (flag ) {
flag = true ;
flag.notifyAll();
}
}
public static void main(String[] args) {
Test test = new Test() ;
test.start();
test.change();
}
}
答案 0 :(得分:0)
您似乎误解了 java 的工作原理。您将一些语言功能混合在一起,因此导致混淆是有道理的。
<块引用>Boolean flag = false ;
这是语法糖:
Boolean flag = Boolean.valueOf(false);
flag 是一个指针(好吧,它是 java,我们称它为引用。potayto potahto)。 flag 当前指向一个全局常量布尔值(系统在启动时生成 2 个布尔对象以提高效率)。
<块引用>synchronized (flag) {
哦,亲爱的。不要那样做。永远不要锁定公开的东西。这不会锁定“标志”,而是锁定标志指向的事物。哪个是全局 false 布尔值。
<块引用>flag = true;
好的,现在 flag
指向全局 true
。
flag.notifyAll();
那是无效的;除非您有锁定,否则您无法通知某事。您在这里锁定了全局 false,而不是全局 true。
但是您既不想锁定全局对象,也不想通知全局对象,因此这一点没有实际意义。
不过,它确实可以解释您的错误。
创建一个私有对象。确保变量只指向一件事。 AtomicBoolean
做到了这一切。只需将 Boolean flag = false
替换为 AtomicBoolean flag = new AtomicBoolean();
,将 flag = true
替换为 flag.set(true)
,至关重要的是,这只是更改所指向对象的属性,而不是更改指针。
请注意,synchronized
是完全没有意义的,除非其他一些代码试图锁定同一事物(synchronized(x)
这样做,其中 x 指向与您正在同步的任何事物相同的事物。