import java.util.*;
import java.io.*;
import java.util.regex.*;
class ZiggyTest2 extends Thread{
String sa;
public ZiggyTest2(String sa){
this.sa = sa;
}
public void run(){
synchronized(sa){
while(!sa.equals("Done")){
try{
sa.wait();
}catch(InterruptedException is){System.out.println("IE Exception");}
}
}
System.out.println(sa);
}
}
class Test{
private static String sa = new String("Not Done");
public static void main(String[] args){
Thread t1 = new ZiggyTest2(sa);
t1.start();
synchronized(sa){
sa = new String("Done");
sa.notify();
}
}
}
當我運行上面的程序,我得到以下異常:線程併發 - 同步和鎖定。
Exception in thread "main" java.lang.IllegalMonitorStateException
at java.lang.Object.notify(Native Method)
at Test.main(ZiggyTest2.java:35)
幾個問題:
爲什麼拋出:IllegalMonitorStateException?由於Test.sa被分配給一個新的String對象,因此我期待ZiggyTest2線程無限期地等待,因爲sa.notify()將在與ZiggyTest2中使用的鎖不同的鎖上被調用。
在上面的示例中,wait()& notify()在「sa」對象上被調用。說自己調用notify()並使用對象調用notify()/ wait()(即sa.wait()和sa.notify()會有什麼不同?
在Test類中,synchronized塊是否具有sa對象的鎖定,sa對象是靜態的,但在ZiggyTest2類中,同步塊使用相同的sa對象引用,但使用非靜態引用?鑑於一個是靜態的,另一個不是,他們是否仍然使用相同的鎖?
謝謝@JB。優秀的解釋。 – ziggy 2011-12-26 14:54:18
但是,即使您在主函數的同步塊中採用全新的字符串引用(根本不使用_sa_),錯誤仍然存在! – Santosh 2011-12-26 15:03:32
你是什麼意思?我解釋說你必須擁有對象監視器來調用對象的通知。如果調用someObject.notify(),則必須在調用synchronized(someObject)之前(並且沒有釋放當然的鎖) – 2011-12-26 15:09:13