在通知上获取非法监视器状态异常

jay*_*att 3 java multithreading

下面的程序应该由两个不同的线程打印偶数和奇数但我在下面的代码中的notify方法上得到非法的监视器异常:

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
            }
        }

    }

}
Run Code Online (Sandbox Code Playgroud)

在同步对象本身上调用notify方法.不知道为什么会这样:

    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)
Run Code Online (Sandbox Code Playgroud)

SMA*_*SMA 6

java包装器中的整数是不可变的,所以一旦你这样做t++,你将分配一个你没有锁定的新的Integer对象,因此你得到了IllegalMonitorStateException.

而不是整数,使用AtomicInteger然后使用incrementAndGetapi来增加计数器的值.