gpt4 book ai didi

java - 在给定的示例代码中什么可能导致 IllegalMonitorStateException

转载 作者:行者123 更新时间:2023-12-02 05:40:18 25 4
gpt4 key购买 nike

我正在尝试学习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/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com