2017-05-02 5 views
1

안녕하세요, Java에서 대기 동작을 테스트하기위한 샘플 프로그램을 작성했습니다.잘못된 모니터 상태 두 개의 쓰레드가 대기 중일 때 예외가 발생합니다.

의 Runnable의 내 구현 :

class ThreadWait implements Runnable { 
    Object lock = new Object(); 
    ThreadWait(Object lock){ 
     this.lock = lock; 
    } 
    @Override 
    public void run() { 
     try { 
      synchronized (lock){ 
       System.out.println("Started : "+Thread.currentThread().getName()); 
       wait(); 
       System.out.println("Completed : "+Thread.currentThread().getName()); 
      } 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
    } 
} 

내에서 사용되는 내 main 같은 :

Exception in thread "A" Exception in thread "B" java.lang.IllegalMonitorStateException 
Started : A 
    at java.lang.Object.wait(Native Method) 
Started : B 
    at java.lang.Object.wait(Object.java:502) 
    at ThreadWait.run(SynchronizedExample.java:34) 
    at java.lang.Thread.run(Thread.java:745) 
java.lang.IllegalMonitorStateException 
    at java.lang.Object.wait(Native Method) 
    at java.lang.Object.wait(Object.java:502) 
    at ThreadWait.run(SynchronizedExample.java:34) 
    at java.lang.Thread.run(Thread.java:745) 
+0

'lock.wait()'...? – MadProgrammer

답변

6

귀하의 문제가 있다는 것입니다 :

Object lock = new Object(); 
ThreadWait t1 = new ThreadWait(lock); 
ThreadWait t2 = new ThreadWait(lock); 
Thread a= new Thread(t1); 
a.setName("A"); 
Thread b= new Thread(t2); 
b.setName("B"); 
a.start(); 
b.start(); 

나는이 예외가 받고이 프로그램을 실행하는 경우 lock에 동기화했으나 기다리고 있습니다. this (구체적으로 대기 호출이 포함 된 실행 가능의 인스턴스).

모니터를 소유하고있는 개체에 대해서만 대기를 호출 할 수 있습니다. 귀하의 코드는 lock이지만, this은 아닙니다!

그러면 잠금 개체를 기다려야합니다. 그러나주의하십시오 : 그러면 코드가 교착 상태가됩니다!

그러면 조언이 나온다. "이론"을 좀 더 공부해야한다. 동일한 데이터에서 작동해야하는 다른 스레드를 "동기화"하기 위해 대기/알림을 사용할 수 있습니다. 그러나 그것은 시행 착오로 당신이 배우는 (효율적으로) 것이 아닙니다. 시행 착오 실험의 결과에 영향을 미치는 미묘한 세부 사항이 너무 많아서 그렇습니다. here 또는 there을 읽을 수 있습니다.

하나의 마지막 단어 : 예, 대기/알림은 중요한 개념임을 이해하는 것이 중요합니다. 하지만 "현실 세계"에서는 거의 사용하지 않습니다. 이것들은 매우 낮은 수준의 메커니즘이며 Java는 그 위에 더 강력한 추상화를 추가했습니다.

+0

문제를 해결해 주셔서 감사합니다. 예, 교착 상태를 만들려고합니다. – robin