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