2009-10-12 2 views
28

왜 이런 일이 생길 수 있습니까?java.lang.IllegalMonitorStateException : (m = null) 모니터를 얻지 못했습니다

java.lang.IllegalMonitorStateException: (m=null) Failed to get monitor for (tIdx=60) 
     at java.lang.Object.wait(Object.java:474) 
     at ... 

이 간단한 풀 솔루션 유발 코드 :

public Object takeObject() { 
     Object obj = internalTakeObject(); 
     while (obj == null) { 
      try { 
       available.wait(); 
      } catch (InterruptedException e) { 
       throw new RuntimeException(e); 
      } 
      obj = internalTakeObject(); 
     } 
     return obj; 
    } 

    private Object internalTakeObject() { 
     Object obj = null; 
     synchronized (available) { 
      if (available.size() > 0) { 
       obj = available.keySet().iterator().next(); 
       available.remove(obj); 
       synchronized (taken) { 
        taken.put(obj, Boolean.valueOf(true)); 
       } 
      } 
     } 
     return obj; 
    } 

    public void returnObject(Object obj) { 
     synchronized (taken) { 
      taken.remove(obj); 
     } 
     synchronized (available) { 
      if (available.size() < size) { 
       available.put(obj, Boolean.valueOf(true)); 
       available.notify(); 
      } 
     } 
    } 

내가 뭔가를 놓치고 것은 모니터 개체를 확실히 null이 아닌,하지만 여전히 우리는 자주이 예외를 얻을 수 있다는 것입니다 ?

편집 : 예외는 available.wait(); 행에서 발생합니다.

+0

소스 코드에서 474 행이 무엇인지 알려주실 수 있습니까? – flybywire

+0

예외는 available.wait()에서 발생합니다. 줄이지만 474 줄은 java.lang.Object 클래스에서 온 것입니다. –

답변

53

에 있어야합니다.

특히 "현재 스레드는이 개체의 모니터를 소유해야합니다." 및 "[throws] IllegalMonitorStateException - 현재의 thread가 객체의 모니터의 소유자가 아닌 경우. 즉, 기다려야 할 객체를 동기화해야합니다. 우리는이 방법 내부 동기화 블록을 작성해야,

synchronized (available) { 
    available.wait(); 
} 
+3

알아야 할 점 :이 예외가'available.notify()'에서 발생하면 같은 패턴을 사용하십시오. –

+0

동일한 작업을 수행하기 위해 블록 대신 동기화 된 함수를 사용했지만 IllegalMonitorStateException을 던졌습니다. 왜 그런가요? –

+0

헌터, 멤버 함수를 동기화 할 때 객체를 잠그고 있습니다. 그래서'this.wait()'가 작동해야합니다. 정확히 * 당신은 무엇을 했습니까? – tgdavies

6

available.wait();이되는 Object.wait를위한 Javadoc을 참조하는 동기 (가능) 섹션

0

takeObject() 메소드가 동기화되어야합니다 또는 :

그래서 당신의 코드가 있어야한다. 나는 이것에 대해 컴파일 타임 예외가 발생하기를 바랍니다.

관련 문제