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 オブジェクトに割り当てられているため、sa.notify() が ZiggyTest2 で使用されているものとは異なるロックで呼び出されるため、ZiggyTest2 スレッドが無期限に待機することを期待していました。
上記の例では、wait() と notify() が「sa」オブジェクトで呼び出されます。単独で notify() を呼び出すことと、オブジェクト、つまり sa.wait() と sa.notify() を使用して notify()/wait() を呼び出すことの違いは何ですか?
Test クラスでは同期ブロックに sa オブジェクトのロックがあり、sa オブジェクトは静的ですが、ZiggyTest2 クラスでは、同期ブロックは同じ sa オブジェクト参照を使用していますが、静的でない参照を使用していますか? 1 つが静的で、もう 1 つが静的ではない場合、両方とも同じロックを引き続き使用しますか?