java同步:illegalmonitorstateexception

xwbd5t1u  于 2021-06-29  发布在  Java
关注(0)|答案(1)|浏览(291)

我不知道程序为什么出错,它抛出 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();
    }

}
eagi6jfj

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 = falseAtomicBoolean flag = new AtomicBoolean(); ,和 flag = trueflag.set(true) ,最关键的是,它只改变了指向的对象的属性,而不是改变指针。
请注意 synchronized 完全没有意义,除非其他代码尝试锁定相同的东西 synchronized(x) 其中x指向与正在同步的对象相同的对象。

相关问题