[英]What can cause IllegalMonitorStateException from inside a synchronized block?
[英]What can cause IllegalMonitorStateException in the given sample code
我正在嘗試學習java並發編程。 請檢查我的示例代碼,並幫助我理解為什么我得到“java.lang.IllegalMonitorStateException”,即使我已調用wait()並在同步上下文中通知。
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
上進行同步, this
在我的例子中是lock
。 編輯:同步上Runnable
是一樣的使用this
,但對我來說,它看起來更好。 膽量告訴我可能會有更多的東西,但我不是這個領域的專家。 專用鎖Object
總是更好,如果您想了解有關該主題的更多信息,請閱讀本文 。
然后,在同步lock
,您必須在同一個對象上調用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();
}
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.