Java 话题 Class : java.lang.IllegalMonitorStateException
Java Thread Class : java.lang.IllegalMonitorStateException
这是我的第一个 post 如果我做错了什么,我深表歉意。
我试图了解 Java 中的线程是如何工作的,特别是同步,这就是为什么我创建了一小段代码,它应该打印 1、2、3、4、5、6(在一个thread) 然后第二个线程等待第一个完成然后打印 6, 5, 4, 3, 2, 1 但它只执行前 6 个步骤并告诉我线程中的等待方法存在监视器问题t2 和通知所有线程 t1 的问题。可能我对对象的同步一无所知。这是我的代码:
public class anObject extends Thread {
long value;
String name;
public anObject(long value, String name) {
this.value = value;
this.name = name;
}
public synchronized void add() {
this.value++;
}
public synchronized void sub() {
this.value--;
}
public static void main(String[] args) {
anObject il = new anObject(0, "Bob");
synchronized (il) {
Thread t1 = new Thread(il) {
public void run() {
while (il.value > 0) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
for (int i = 0; i < 6; i++) {
il.add();
System.out.println(il.value);
try {
sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
il.notifyAll();
}
};
Thread t2 = new Thread(il) {
public void run() {
while (il.value < 6) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
for (int j = 0; j < 6; j++) {
il.sub();
System.out.println(il.value);
try {
sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
il.notifyAll();
}
};
t1.start();
t2.start();
}
}
}
这就是终端中出现的内容:
Exception in thread "Thread-2" 1
java.lang.IllegalMonitorStateException
at java.lang.Object.wait(Native Method)
at java.lang.Object.wait(Unknown Source)
at anObject.run(anObject.java:53)
2
3
4
5
6
Exception in thread "Thread-1" java.lang.IllegalMonitorStateException
at java.lang.Object.notifyAll(Native Method)
at anObject.run(anObject.java:45)
非常感谢您的帮助!
问候
你在做什么
synchronized (il)
只是从主线程中获取一个对象的监视器。但是在内部,您正在初始化两个新线程,并尝试从这两个最近初始化然后启动的线程的上下文中调用 wait()
方法。 IllegalMonitorStateException 的主要思想是您正在尝试调用一个使用对象锁定上下文的方法,而无需在此对象的锁定之前 obtaining 。你可以做些什么来快速修复它只是改变
while (il.value > 0) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
于
while (il.value > 0) {
try {
synchronized(this) {
this.wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
并在第二个代码块中进行相同的更改。但要真正做到正确,我建议您转向一些 强大的来源 描述多线程概念。我想 Oracle 的基本 java 教程就可以了。
wait 是在 Object 中定义的,这就是你得到这个异常的原因。
我更喜欢专用 lock 以避免不可预测的监视器异常:
private final Object lock = new Object();
private static final class Lock { }
private final Object lock = new Lock();
对于notify或notifyAll一个对象,需要用synchronized语句持有锁。另外,您应该定义一个循环来检查唤醒条件。
synchronized (lock) {
while (!isWakeupNeeded()) {
lock.wait();
}
}
通知:
synchronized (lock) {
makeWakeupNeeded();
lock.notifyAll();
}
这是我的第一个 post 如果我做错了什么,我深表歉意。 我试图了解 Java 中的线程是如何工作的,特别是同步,这就是为什么我创建了一小段代码,它应该打印 1、2、3、4、5、6(在一个thread) 然后第二个线程等待第一个完成然后打印 6, 5, 4, 3, 2, 1 但它只执行前 6 个步骤并告诉我线程中的等待方法存在监视器问题t2 和通知所有线程 t1 的问题。可能我对对象的同步一无所知。这是我的代码:
public class anObject extends Thread {
long value;
String name;
public anObject(long value, String name) {
this.value = value;
this.name = name;
}
public synchronized void add() {
this.value++;
}
public synchronized void sub() {
this.value--;
}
public static void main(String[] args) {
anObject il = new anObject(0, "Bob");
synchronized (il) {
Thread t1 = new Thread(il) {
public void run() {
while (il.value > 0) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
for (int i = 0; i < 6; i++) {
il.add();
System.out.println(il.value);
try {
sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
il.notifyAll();
}
};
Thread t2 = new Thread(il) {
public void run() {
while (il.value < 6) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
for (int j = 0; j < 6; j++) {
il.sub();
System.out.println(il.value);
try {
sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
il.notifyAll();
}
};
t1.start();
t2.start();
}
}
}
这就是终端中出现的内容:
Exception in thread "Thread-2" 1
java.lang.IllegalMonitorStateException
at java.lang.Object.wait(Native Method)
at java.lang.Object.wait(Unknown Source)
at anObject.run(anObject.java:53)
2
3
4
5
6
Exception in thread "Thread-1" java.lang.IllegalMonitorStateException
at java.lang.Object.notifyAll(Native Method)
at anObject.run(anObject.java:45)
非常感谢您的帮助! 问候
你在做什么
synchronized (il)
只是从主线程中获取一个对象的监视器。但是在内部,您正在初始化两个新线程,并尝试从这两个最近初始化然后启动的线程的上下文中调用 wait()
方法。 IllegalMonitorStateException 的主要思想是您正在尝试调用一个使用对象锁定上下文的方法,而无需在此对象的锁定之前 obtaining 。你可以做些什么来快速修复它只是改变
while (il.value > 0) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
于
while (il.value > 0) {
try {
synchronized(this) {
this.wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
并在第二个代码块中进行相同的更改。但要真正做到正确,我建议您转向一些 强大的来源 描述多线程概念。我想 Oracle 的基本 java 教程就可以了。
wait 是在 Object 中定义的,这就是你得到这个异常的原因。
我更喜欢专用 lock 以避免不可预测的监视器异常:
private final Object lock = new Object();
private static final class Lock { }
private final Object lock = new Lock();
对于notify或notifyAll一个对象,需要用synchronized语句持有锁。另外,您应该定义一个循环来检查唤醒条件。
synchronized (lock) {
while (!isWakeupNeeded()) {
lock.wait();
}
}
通知:
synchronized (lock) {
makeWakeupNeeded();
lock.notifyAll();
}