1 java illegalmonitorstateexcep notify wait
我刚接触在Java中使用wait()和notify(),我得到一个IllegalMonitorStateException.
主要代码
public class ThreadTest {
private static Integer state = 0;
public static void main(String[] args) {
synchronized(state) {
System.out.println("Starting thread");
Thread t = new Thread(new AnotherTest());
t.start();
synchronized(state) {
state = 0;
while(state == 0) {
try {
state.wait(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("State is: " + state);
}
}
}
public static class AnotherTest implements Runnable {
@Override
public void run() {
synchronized(state) {
state = 1;
state.notify();
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
我收到一个IllegalMonitorStateException调用state.notify().有任何想法吗?
编辑:根据下面的答案,这里的代码是有效的.作为旁注,我首先尝试使用枚举,这与使用Integer有同样的问题.
public class ThreadTest {
private static int state = 0;
private static Object monitor = new Object();
public static void main(String[] args) {
synchronized(monitor) {
System.out.println("Starting thread");
Thread t = new Thread(new AnotherTest());
t.start();
state = 0;
while(state == 0) {
try {
for(int i = 0; i < 5; i++) {
System.out.println("Waiting " + (5 - i) + " Seconds");
Thread.sleep(1000);
}
monitor.wait(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("State is: " + state);
}
}
public static class AnotherTest implements Runnable {
@Override
public void run() {
synchronized(monitor) {
state = 1;
monitor.notify();
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
这个
private static Integer state = 0;
Run Code Online (Sandbox Code Playgroud)
相当于
private static Integer state = Integer.valueOf(0);
Run Code Online (Sandbox Code Playgroud)
调用valueOf(0)返回Integer对象的引用,称之为A.
然后你这样做
synchronized(state) {
Run Code Online (Sandbox Code Playgroud)
你的线程获取对引用的对象的锁定state,目前是A.
然后你这样做
state = 1;
Run Code Online (Sandbox Code Playgroud)
这相当于
state = Integer.valueOf(1);
Run Code Online (Sandbox Code Playgroud)
它为您提供了对Integer对象的不同引用,将其称为B,并将其分配给state.然后你打电话
state.notify();
Run Code Online (Sandbox Code Playgroud)
你正在调用notify()一个对象B,你的线程不拥有该监视器.您不能调用notify或wait在您的线程不拥有该监视器的对象上.