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 객체에 할당되었으므로 saigger()가 ZiggyTest2에서 사용 된 잠금과 다른 잠금에서 호출되기 때문에 ZiggyTest2 스레드가 무한정 대기 할 것으로 예상했습니다.
위 예제에서 wait() & notify()가 "sa"개체에서 호출되었습니다. notify()를 호출하고 notify()/wait()를 호출하는 것, 즉 sa.wait() 및 sa.notify()를 사용하는 것의 차이점은 무엇입니까?
테스트 클래스에서 동기화 된 블록은 sa 객체에 대한 잠금을 가지며 sa 객체는 정적이지만 ZiggyTest2 클래스에서 동기화 된 블록은 동일한 sa 객체 참조를 사용하지만 비 정적 참조 ? 하나는 정적이고 다른 하나는 그렇지 않다는 것을 감안할 때, 둘 다 여전히 동일한 잠금을 사용합니까?
감사합니다. @JB. 훌륭한 설명. – ziggy
그러나 주 기능의 동기화 된 블록에서 완전히 새로운 문자열 참조 (전혀 _sa_를 사용하지 않음)를 사용하더라도 여전히 오류가 발생합니다! – Santosh
무엇을 의미합니까? 나는 당신이 객체에 대한 통지를 호출하기 위해 객체 모니터를 소유해야한다고 설명했다. someObject.notify()를 호출하면 synchronized (someObject)를 호출해야합니다 (물론 잠금을 해제하지 않았 음) –