public class Bees {
public static void main(String[] args) {
try {
new Bees().go();
} catch (Exception e) {
System.out.println("thrown to main" + e);
}
}
synchronized void go() throws InterruptedException {
Thread t1 = new Thread();
t1.start();
System.out.print("1 ");
t1.wait(5000);
System.out.print("2 ");
}
}
本程序的输出是:
1 thrown to main
我不明白为什么thrown to main
来到这里。
答案 0 :(得分:5)
您收到java.lang.IllegalMonitorStateException
,因为您在wait()
上调用的对象t1
不拥有同步锁。
请注意,当您将方法声明为synchronized
时,该方法的锁定所有者是当前对象(在这种情况下,您的Bees
实例)。如果您想在wait()
上致电t1
,则需要在t1
上进行同步:
...
Thread t1 = new Thread();
synchronized(t1) {
t1.start();
System.out.print("1 ");
t1.wait(5000);
}
...
另外,在捕获异常时,应始终将异常本身包含在日志输出中,至少要像
一样...
} catch (Exception e) {
System.out.println("thrown to main" + e);
}
...
否则您可能会错过重要信息(例如实际引发的异常)。
答案 1 :(得分:2)
您需要从wait
块内调用synchronized
。当前线程应该在等待之前获取对象的监视器。
从JavaDoc复制:
当前线程必须拥有此对象的监视器。线程释放此监视器的所有权并等待,直到另一个线程通过调用notify方法或notifyAll方法通知等待此对象监视器的线程唤醒。然后该线程等待,直到它可以重新获得监视器的所有权并继续执行。
synchronized (obj) {
while (<condition does not hold>)
obj.wait();
... // Perform action appropriate to condition
}