同步时引发IllegalMonitorStateException

时间:2019-11-13 08:15:48

标签: java concurrency

我正在用Java学习多线程。现在我必须从三个不同的线程打印1 2 3 1 2 3...。我知道还存在其他解决方案,但是我需要了解为什么会引发异常。 根据oracle docs https://docs.oracle.com/javase/7/docs/api/java/lang/IllegalMonitorStateException.html,在不拥有监视器的情况下调用wait或notify时会抛出该错误。 我想知道同步是否在Main对象上,为什么不拥有它。 这是我的代码

class ThreadA implements Runnable {
    Main main;
    Object o = new Object();

    ThreadA(Main m) {
        this.main = m;
    }

    @Override
    public void run() {
        synchronized (main) {
            while (main.val == 1) {
                System.out.println(Thread.currentThread().getName());
                main.val = 2;
                try {
                    wait();
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }

            }
            notifyAll();
        }

    }

}

class ThreadB implements Runnable {

    Main main;
    Object o = new Object();

    ThreadB(Main m) {
        this.main = m;
    }

    @Override
    public void run() {
        synchronized (main) {
            while (main.val == 2) {
                System.out.println(Thread.currentThread().getName());
                main.val = 3;
                try {

                    wait();
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }

            }
            notifyAll();
        }
    }

}

class ThreadC implements Runnable {
    Main main;
    Object o = new Object();

    ThreadC(Main m) {
        this.main = m;
    }

    @Override
    public void run() {
        synchronized (main) {
            while (main.val == 3) {
                System.out.println(Thread.currentThread().getName());
                main.val = 1;
                try {

                    wait();
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }

            }
            notifyAll();
        }
    }

}

public class Main {
    volatile static int val = 1;

    public static void main(String[] args) {

        Main m = new Main();
        Thread A = new Thread(new ThreadA(m), "TA");
        Thread B = new Thread(new ThreadB(m), "TB");
        Thread C = new Thread(new ThreadC(m), "TC");

        A.start();
        B.start();
        C.start();
    }

}

1 个答案:

答案 0 :(得分:0)

我找到了解决方案。它应该是main.wait()和main.notify()