java - 通知时获取非法监视器状态异常

标签 java multithreading

下面的程序应该通过两个不同的线程打印偶数和奇数,但是我在下面的代码中的通知方法上遇到非法监视器异常:

public class oddeven {
    static volatile Integer t = 0;

    public static void main(String as[]) {
        oddrunnable or = new oddrunnable(t);
        evenrunnable er = new evenrunnable(t);

        Thread t1 = new Thread(or, "odd");
        Thread t2 = new Thread(er, "even");

        t1.start();
        t2.start();

    }

}

class oddrunnable implements Runnable {
    Integer t;

    public oddrunnable(Integer t) {
        this.t = t;
    }

    @Override
    public void run() {
        // TODO Auto-generated method stub

        synchronized (t) {
            while (true) {

                if (t % 2 == 0) {
                    try {
                        t.wait();
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
                System.out.println("Current thread id " + Thread.currentThread().getName());
                t++;
                t.notify();
            }
        }
    }

}

class evenrunnable implements Runnable {
    Integer t;

    public evenrunnable(Integer t) {
        this.t = t;
    }

    @Override
    public void run() {
        // TODO Auto-generated method stub

        // TODO Auto-generated method stub

        synchronized (t) {
            while (true) {

                if (t % 2 != 0) {
                    try {
                        t.wait();
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
                System.out.println("Current thread id " + Thread.currentThread().getName());
                t++;
                t.notify(); // <-------------------exception on this line
            }
        }

    }

}

通知方法在同步对象本身上被调用。不确定为什么会这样:

    Current thread id even
Exception in thread "even" java.lang.IllegalMonitorStateException
    at java.lang.Object.notify(Native Method)
    at evenrunnable.run(oddeven.java:86)
    at java.lang.Thread.run(Thread.java:619)

最佳答案

Java 包装器中的整数是不可变的,所以一旦您执行 t++,您将分配一个您没有锁定的新 Integer 对象,因此您会得到 IllegalMonitorStateException

使用 AtomicInteger 代替 Integer,然后使用 incrementAndGet api 来增加计数器的值。

关于java - 通知时获取非法监视器状态异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34435631/

相关文章:

.net - Thread.abort永远挂起

c++ - TBB 中的 TLS enumerable_thread_specific

python - 在不使用 os.chdir() 的情况下在 python 中创建相对符号链接(symbolic link)

c++ - 如何使用循环中的所有内核?

java - JFrame 窗口拒绝打开

java - 将文本从 Microsoft Word 复制到 JTextPane

java - 使用 Jsch 将 java textarea 作为输入流以交互模式运行 shell 命令

java - 如果使用 SVN checkin 某些内容,如何配置 Jenkins 自动构建项目?

java - 使用 Spring AOP 捕获 Http 状态代码的正确方法是什么?

java - 在 Java EE 中限制对特定方法的多次访问的过程