我正在尝试学习java并发编程。请检查我的示例代码并帮助我理解为什么我会收到“java.lang.IllegalMonitorStateException”,即使我在同步上下文中调用了 wait() 和 notification。
public class Test {
public static void main(String[] args) throws Exception {
Test t1 = new Test();
t1.m1();
}
private void m1() {
Example ex = new Example();
Thread t1 = new Thread(ex);
t1.start();
synchronized (ex) {
System.out.println("waiting");
try {
wait();
} catch (Exception e) {
e.printStackTrace();
}
}
}
public class Example implements Runnable {
@Override
public void run() {
System.out.println("Running");
notifyMethod();
}
private void notifyMethod() {
System.out.println("Notifying");
synchronized (this) {
try {
Thread.sleep(1000);
} catch (Exception ex) {
ex.printStackTrace();
}
notify();
}
}
}
}
我期望“等待、运行、通知”,但实际输出是:
waiting
Running
java.lang.IllegalMonitorStateException
Notifying
at java.lang.Object.wait(Native Method)
at java.lang.Object.wait(Object.java:502)
at examples.Test.m1(Test.java:18)
at examples.Test.main(Test.java:8)
最佳答案
首先,我认为在 Runnable
上同步不是一个好主意(在您的情况下是Example
)。您可以在 this
上同步,或者更好的是在专用的 Object
上同步,在我的示例中即为 lock
。 编辑:在Runnable
上同步与使用this
相同,但对我来说它看起来更好。直觉告诉我可能还有更多的事情,但我不是这个领域的专家。专用锁 Object
总是更好,请阅读 this article如果您想了解有关该主题的更多信息。
然后,在同步锁
时,您必须对同一对象调用wait()
:lock.wait()
。如果您在 this
上进行同步,则调用 this.wait()
或仅调用 wait()
。
当您想要通知等待线程时,您必须再次同步lock
并对该对象调用notify()
:lock.notify( )
。同步中的监视器和您调用 notify()
的对象都必须与您调用 wait()
的对象完全相同。
这是一个有效的代码:
public class Test {
public static final Object lock = new Object();
public static void main(String[] args) throws Exception {
Test t1 = new Test();
t1.m1();
}
private void m1() {
Example ex = new Example();
Thread t1 = new Thread(ex);
t1.start();
synchronized (lock) {
System.out.println("waiting");
try {
lock.wait();
} catch (Exception e) {
e.printStackTrace();
}
}
}
public static class Example implements Runnable {
@Override
public void run() {
System.out.println("Running");
notifyMethod();
}
private void notifyMethod() {
System.out.println("Notifying");
synchronized (lock) {
try {
Thread.sleep(1000);
} catch (Exception ex) {
ex.printStackTrace();
}
lock.notify();
}
}
}
}
关于java - 在给定的示例代码中什么可能导致 IllegalMonitorStateException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56143664/