Java 如何修复使用wait和notify时的IllegalMonitorStateException?
我有一个JPanel类,它使用“implements runnable”启动另一个线程。然后,另一个线程将在不同点调用JPanel类中的一个方法,这样做时,该方法将需要等待用户输入。我尝试过这样实现它: 由需要等待的其他线程调用的JPanel类中的方法:Java 如何修复使用wait和notify时的IllegalMonitorStateException?,java,multithreading,wait,notify,Java,Multithreading,Wait,Notify,我有一个JPanel类,它使用“implements runnable”启动另一个线程。然后,另一个线程将在不同点调用JPanel类中的一个方法,这样做时,该方法将需要等待用户输入。我尝试过这样实现它: 由需要等待的其他线程调用的JPanel类中的方法: public void methodToWait() { while(conditionIsMet) { try { wait(); } c
public void methodToWait()
{
while(conditionIsMet)
{
try
{
wait();
}
catch
{
e.printStackTrace();
}
}
}
JPanel类中通知等待用户输入的方法:
public void mouseClicked(MouseEvent event)
{
notifyAll();
}
但是,在运行应用程序时,它会在调用wait时抛出一个“java.lang.IllegalMonitorStateException”,为什么要这样做,以及如何解决问题?请参阅的文档,以及:
Thorws IllegalMonitorStateException-如果当前线程不是
对象监视器的所有者
这意味着您在获得监视器锁之前不能调用它们,换句话说,在输入块或同步方法之前(查看更多信息)
另一件重要的事情是,您应该在同一个对象上同步
- 将同步块与explict对象一起使用时,应在此对象上调用
和wait
notify
- 当您使用synchronized方法时,您是在
上隐式同步,因此您应该调用this
和this.wait()
(关键字this.notify()
不是强制的)this
在这种情况下,您需要创建一个
对象
作为监视器锁,并在不同的类之间共享它
合规示例:
synchronized (obj) {
while (<condition does not hold>)
obj.wait();
... // Perform action appropriate to condition
}
synchronized (obj) {
... // Prepare the condition
obj.notifyAll();
}
void waitMethod() {
wait(); // throws IllegalMonitorStateException
}
void notifyMethod() {
notify(); // throws IllegalMonitorStateException
}
synchronized (obj1) {
while (<condition does not hold>)
obj1.wait();
... // Perform action appropriate to condition
}
synchronized (obj2) {
... // call notifyAll on obj2 will not stop the wait on obj1
obj2.notifyAll();
}
in class1
synchronized void waitMethod() {
while(someCondition()) {
wait();
}
}
in class2
synchronized void notifyMethod() {
notify(); // call notifyAll on class2 will not stop the wait on class1
}
不合规示例:
synchronized (obj) {
while (<condition does not hold>)
obj.wait();
... // Perform action appropriate to condition
}
synchronized (obj) {
... // Prepare the condition
obj.notifyAll();
}
void waitMethod() {
wait(); // throws IllegalMonitorStateException
}
void notifyMethod() {
notify(); // throws IllegalMonitorStateException
}
synchronized (obj1) {
while (<condition does not hold>)
obj1.wait();
... // Perform action appropriate to condition
}
synchronized (obj2) {
... // call notifyAll on obj2 will not stop the wait on obj1
obj2.notifyAll();
}
in class1
synchronized void waitMethod() {
while(someCondition()) {
wait();
}
}
in class2
synchronized void notifyMethod() {
notify(); // call notifyAll on class2 will not stop the wait on class1
}
谢谢,异常已停止,但notifyAll不会停止等待。是不是因为mouseClicked事件位于单独的“类”中?其中,它位于:this.table.addMouseListener(newMouseAdapter()下)@Jason说得对。你需要在同一个对象上进行同步。你可以创建一个
对象进行同步,并在不同的类中共享此对象。非常感谢你,不知道为什么我花了两次时间才理解它,因为它现在看起来很简单!@Jason很乐意帮助:)如果您不知道为什么Java会在调用o.wait()
之前强制您锁定互斥锁,那么您可能可以从本教程中学到一些东西: