【发布时间】:2012-12-02 14:13:13
【问题描述】:
public class newTest{
/**
* @param args
*/
public static Integer x = new Integer(0);
public static void main(String[] args) {
newTest tstobj = new newTest();
// TODO Auto-generated method stub
MyThread t = tstobj.new MyThread();
t.start();
tstobj.incrementX();
System.out.println(x.intValue());
try {
t.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public synchronized void incrementX(){
try {
while(x != 5){
x.wait();
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public class MyThread extends Thread{
newTest tstobj = new newTest();
public void run() {
// TODO Auto-generated method stub
tstobj.incrementX();
}
}
}
我不确定为什么这段代码会导致 IllegalMonitorStateException 而不是无限循环。具体来说,这段代码有两个线程 1. 主线程 2. MyThread 他们都尝试调用一个名为 incrementX() 的同步方法,所以假设两个线程之一通过获取锁进入同步方法,然后它看到 x != 5 所以它调用等待,这将释放锁并将放置在等待队列中,等待调用同步方法的下一个线程将通过获取锁进入并看到 x != 5 并调用等待,这将挂起线程并放入等待队列。现在两个线程在等待队列中什么都不做,这应该会导致一个无限循环。但是这段代码会导致非法MonitorStateException?
这段代码不会做任何有用的事情,但我想了解我在概念上哪里出错了?我查看了很多材料,但仍然无法弄清楚我对代码的期望有什么问题。任何帮助都会很棒。谢谢
【问题讨论】:
-
关键错误是在与您调用其等待方法的对象不同的对象上同步。将方法标记为“已同步”等同于对此进行同步。它可能有助于停止写作,并且可能会以“同步”的方式思考,而改为以“同步于...”的方式思考。
标签: java multithreading object wait