今天看了一篇線程通信的文章。想着研究一下線程之間的通信,使用的是object方法的wait和notify進行實作。代碼如下:
public static void demo2() {
final Thread A = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("A1");
try {
//調用wait,notify,notifyAll時,必須要擁有該對象的鎖
//如果沒有擁有該對象的鎖卻調用該對象的wait,notify,notifyAll方法
//就會報出IllegalMonitorStateException異常
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("A2");
System.out.println("A3");
}
});
Thread B = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("B1");
System.out.println("B2");
System.out.println("B3");
lock.notify();
}
});
A.start();
B.start();
}
編譯不報錯,但是運作程式時報錯,報錯如下:
Exception in thread "Thread-0" A1
B1
B2
B3
Exception in thread "Thread-1" java.lang.IllegalMonitorStateException
at java.lang.Object.wait(Native Method)
at java.lang.Object.wait(Object.java:502)
at cn.org.bjca.ThreadCommunicate$3.run(ThreadCommunicate.java:57)
at java.lang.Thread.run(Thread.java:745)
java.lang.IllegalMonitorStateException
at java.lang.Object.notify(Native Method)
at cn.org.bjca.ThreadCommunicate$4.run(ThreadCommunicate.java:71)
at java.lang.Thread.run(Thread.java:745)
Process finished with exit code 0
在網上搜尋了一下,知道了原因,特在此記錄一下。
調用wait,notify,notifyAll時,必須要擁有該對象的鎖,
如果沒有擁有該對象的鎖卻調用該對象的wait,notify,notifyAll方法
就會報出IllegalMonitorStateException異常
擷取一個對象鎖的最簡單方式是使用synchronized關鍵字。
代碼修改如下:
public static void demo2() {
final Object lock = new Object();
final Thread A = new Thread(new Runnable() {
@Override
public void run() {
synchronized (lock){
System.out.println("A1");
try {
//調用wait,notify,notifyAll時,必須要擁有該對象的鎖
//如果沒有擁有該對象的鎖卻調用該對象的wait,notify,notifyAll方法
//就會報出IllegalMonitorStateException異常
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("A2");
System.out.println("A3");
}
}
});
Thread B = new Thread(new Runnable() {
@Override
public void run() {
synchronized (lock){
System.out.println("B1");
System.out.println("B2");
System.out.println("B3");
lock.notify();
}
}
});
A.start();
B.start();
}
OK,問題解決,程式可以正常執行。