Java 如何修复使用wait和notify时的IllegalMonitorStateException?

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

我有一个JPanel类,它使用“implements runnable”启动另一个线程。然后,另一个线程将在不同点调用JPanel类中的一个方法,这样做时,该方法将需要等待用户输入。我尝试过这样实现它:

由需要等待的其他线程调用的JPanel类中的方法:

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()
之前强制您锁定互斥锁,那么您可能可以从本教程中学到一些东西: