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

Jas*_*son 3 java multithreading notify wait

我有一个JPanel类,它使用"implements runnable"启动另一个线程.然后,这个其他线程将在各个点调用JPanel类中的一个方法,然后这样做将需要等待用户输入.我试图像这样实现它:

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

public void methodToWait()
{
    while(conditionIsMet)
    {
        try
        {
            wait();
        }
        catch
        {
            e.printStackTrace();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

JPanel类中的方法,用于通知用户输入的等待:

public void mouseClicked(MouseEvent event)
{
    notifyAll();
}
Run Code Online (Sandbox Code Playgroud)

但是,在运行应用程序时,它会在调用wait时抛出"java.lang.IllegalMonitorStateException",为什么要执行此操作以及如何解决此问题?

孙兴斌*_*孙兴斌 5

见的文档wait,notify并且notifyAll:

Thorws IllegalMonitorStateException - 如果当前线程不是对象监视器的所有者.

这意味着在获得监视器锁之前,您无法调用它们,换句话说,直到您输入了synchronized块或synchronized方法(请查看此内容以获取更多信息).


另一个重要的事情是,您应该在同一个对象上进行同步.

  • 当您使用synchronized块用显式的对象,你应该调用waitnotify这个对象上.
  • 当你使用synchronized方法时,你是在暗示同步this,所以你应该调用this.wait()this.notify()(关键字this不是mandory).

在这种情况下,您需要创建一个Object监视器锁并在不同的类之间共享它.


符合示例:

synchronized (obj) {
    while (<condition does not hold>)
        obj.wait();
    ... // Perform action appropriate to condition
}

synchronized (obj) {
    ... // Prepare the condition
    obj.notifyAll();
}
Run Code Online (Sandbox Code Playgroud)

不合规的例子:

void waitMethod() {
    wait(); // throws IllegalMonitorStateException  
}

void notifyMethod() {
    notify(); // throws IllegalMonitorStateException  
}
Run Code Online (Sandbox Code Playgroud)

不合规的例子:

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();
}
Run Code Online (Sandbox Code Playgroud)

不合规的例子:

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
}
Run Code Online (Sandbox Code Playgroud)