【问题标题】:IllegalMonitorStateException when use .class as monitor while "this" not [duplicate]IllegalMonitorStateException 使用 .class 作为监视器而“this”不是 [重复]
【发布时间】:2021-02-11 09:13:52
【问题描述】:

我刚刚写了一个程序,用两个线程轮流打印 0-99。我使用同步块来完成工作。在我的代码中,当我使用“this”作为同步监视器时,程序运行良好。但是当我使用“.class”作为同步监视器时,我得到了IllegalMonitorStateException。谁能告诉我发生了什么?

这是我运行良好的代码

public class WaitTest implements Runnable {
    private int n = 0;

    @Override
    public void run() {
        while (true) {
            synchronized (this){
                notify();
                if (n < 100) {

                    System.out.println(Thread.currentThread().getName() + " " + Integer.toString(n));
                    ++n;
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    try {
                        wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                } else
                    break;
            }
        }
    }

    public static void main(String[] args) {
        WaitTest waitTest = new WaitTest();
        Thread threadA = new Thread(waitTest);
        Thread threadB = new Thread(waitTest);
        threadA.start();
        threadB.start();
    }
}

这是我遇到异常的代码

public class WaitTest implements Runnable {
    private int n = 0;

    @Override
    public void run() {
        while (true) {
            synchronized (WaitTest.class){
                notify();
                if (n < 100) {

                    System.out.println(Thread.currentThread().getName() + " " + Integer.toString(n));
                    ++n;
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    try {
                        wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                } else
                    break;
            }
        }
    }

    public static void main(String[] args) {
        WaitTest waitTest = new WaitTest();
        Thread threadA = new Thread(waitTest);
        Thread threadB = new Thread(waitTest);
        threadA.start();
        threadB.start();
    }
}

它们之间唯一的区别是同步后大括号中的内容

【问题讨论】:

    标签: java multithreading parallel-processing thread-safety


    【解决方案1】:

    在我的代码中,当我使用“this”作为同步监视器时,程序 效果很好。

    这是因为当您调用 wait()notify() 方法时,您是从 this 的实例返回中隐式调用它们,这与您的同步子句中使用的对象相匹配(即 em>synchronized (this))。

    但是当我使用“.class”作为同步监视器时,我得到了 IllegalMonitorStateException。

    发生这种情况是因为您在 WaitTest.class 类上进行了同步,但您再次为 this 实例调用了 waitnotify 方法。因此,为避免该异常,请将wait(); and notify(); 的调用分别更改为WaitTest.class.wait();WaitTest.class.notify();

    代码修正:

    public class WaitTest implements Runnable {
        private int n = 0;
    
        @Override
        public void run() {
            while (true) {
                synchronized (WaitTest.class){
                    WaitTest.class.notify();
                    if (n < 100) {
    
                        System.out.println(Thread.currentThread().getName() + " " + Integer.toString(n));
                        ++n;
                        try {
                            Thread.sleep(100);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        try {
                            WaitTest.class.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
    
                    } else
                        break;
                }
            }
        }
    
        public static void main(String[] args) {
            WaitTest waitTest = new WaitTest();
            Thread threadA = new Thread(waitTest);
            Thread threadB = new Thread(waitTest);
            threadA.start();
            threadB.start();
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2013-12-28
      • 1970-01-01
      • 2018-06-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-04-06
      • 2018-01-04
      • 1970-01-01
      相关资源
      最近更新 更多