使用等待和通知时如何修复 IllegalMonitorStateException?
How to fix IllegalMonitorStateException when using wait and notify?
我有一个 JPanel class,它使用 "implements runnable" 启动另一个线程。这个另一个线程然后将在不同的点调用 JPanel class 中的一个方法,这样做将需要等待用户输入。我试图像这样实现它:
JPanel 中的方法class 被需要等待的其他线程调用:
public void methodToWait()
{
while(conditionIsMet)
{
try
{
wait();
}
catch
{
e.printStackTrace();
}
}
}
JPanel 中的方法 class 在等待用户输入时发出通知:
public void mouseClicked(MouseEvent event)
{
notifyAll();
}
但是,运行 应用程序在调用等待时抛出 "java.lang.IllegalMonitorStateException",为什么会这样,我该如何解决这个问题?
参见 wait
, notify
and notifyAll
的文档:
Thorws IllegalMonitorStateException - if the current thread is not the
owner of the object's monitor.
这意味着在您获得监视器锁之前,您不能调用它们,换句话说,在您进入 synchronized block or synchronized method(check this for more 之前。
另一件重要的事情是,你应该在同一个对象上同步。
- 当您对显式对象使用 同步块 时,您应该对该对象调用
wait
和 notify
。
- 当您使用 同步方法 时,您是在
this
上隐式同步,因此您应该调用 this.wait()
和 this.notify()
(关键字 this
不是强制性的)。
在这种情况下,您需要创建一个 Object
作为监视器锁并在不同的 类 之间共享它。
合规示例:
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
}
我有一个 JPanel class,它使用 "implements runnable" 启动另一个线程。这个另一个线程然后将在不同的点调用 JPanel class 中的一个方法,这样做将需要等待用户输入。我试图像这样实现它:
JPanel 中的方法class 被需要等待的其他线程调用:
public void methodToWait()
{
while(conditionIsMet)
{
try
{
wait();
}
catch
{
e.printStackTrace();
}
}
}
JPanel 中的方法 class 在等待用户输入时发出通知:
public void mouseClicked(MouseEvent event)
{
notifyAll();
}
但是,运行 应用程序在调用等待时抛出 "java.lang.IllegalMonitorStateException",为什么会这样,我该如何解决这个问题?
参见 wait
, notify
and notifyAll
的文档:
Thorws IllegalMonitorStateException - if the current thread is not the owner of the object's monitor.
这意味着在您获得监视器锁之前,您不能调用它们,换句话说,在您进入 synchronized block or synchronized method(check this for more 之前。
另一件重要的事情是,你应该在同一个对象上同步。
- 当您对显式对象使用 同步块 时,您应该对该对象调用
wait
和notify
。 - 当您使用 同步方法 时,您是在
this
上隐式同步,因此您应该调用this.wait()
和this.notify()
(关键字this
不是强制性的)。
在这种情况下,您需要创建一个 Object
作为监视器锁并在不同的 类 之间共享它。
合规示例:
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
}