我不知道程序为什么出错,它抛出 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();
}
}
1条答案
按热度按时间eagi6jfj1#
你似乎误解了java的工作原理。您将一些语言特性混合在一起,因此这在一定程度上导致了混淆。
Boolean flag = false ;
这是用于:Boolean flag = Boolean.valueOf(false);
flag是一个指针(好吧,它是java,我们称它为引用)。波塔托波塔托)。标志当前指向一个全局常量布尔值(为了提高效率,系统在启动时生成2个布尔值对象)。synchronized (flag) {
哦,亲爱的。别那么做。永远不要锁定公共物品。这不会锁定“flag”,而是锁定flag指向的对象。这是全局假布尔值。flag = true;
好吧,现在flag
指向全局true
.flag.notifyAll();
那是无效的;除非你有锁,否则你不能通知什么东西。你在这里锁定了全局假,而不是全局真。但你既不想锁定某个全局性的东西,也不想通知那个全局性的东西,所以这一点毫无意义。
不过,这也解释了你的错误。
好吧那我该怎么办?
创建私有对象。确保变量只指向一件事。
AtomicBoolean
做所有这些。只要替换一下Boolean flag = false
与AtomicBoolean flag = new AtomicBoolean();
,和flag = true
与flag.set(true)
,最关键的是,它只改变了指向的对象的属性,而不是改变指针。请注意
synchronized
完全没有意义,除非其他代码尝试锁定相同的东西synchronized(x)
其中x指向与正在同步的对象相同的对象。