왜 wait() 메소드는 항상 synchronized 블록 안에 있는거죠?


Object.wait()메소드를 발생시키려면 메소드가 반드시 synchronized 블록 안에 있어야 한다는 것은 모두가 아는 사실입니다. 그렇지 않으면 IllegalMonitorStateException이 발생하겠죠. 왜 이러한 제한을 두는 이유가 무엇이죠? wait()메소드가 monitor를 release하는 것은 알고 있습니다만, 왜 synchronized 블록을 따로 만든 후에 wait()메소드를 호출하는 방법을 통해서 명시적으로 monitor를 얻어야 하는 것인가요?

wait()을 동기화 블럭 외부에서 실행한다면, 즉 의미를 유지한 채, 호출 스레드를 지연 시킬때 발생하는 잠재적 위험은 무엇입니까?

  • 2016년 07월 17일에 작성됨

조회수 108


1 답변


좋아요
0
싫어요
채택취소하기

Wait()는 notify()메소드 또한 존재할 때 의미가 있는 메소드입니다. 그래서 항상 스레드간의 상호작용과 관련이 있으며 제대로 작동하기 위해서는 synchronization이 필요한거죠. 이러한 과정들이 암시적이어야 하는 것이 아닌가라고 생각할 수 있지만 다음과 같은 이유 때문에 전혀 도움이 되지 않습니다:

의미상 항상 wait()하는 것만은 아닙니다. 만족시켜야할 condition이 존재하고요 그렇지 않다면 만족될 때까지 wait합니다. 다음과 같이 작동하겠죠.

if(!condition){
    wait();
}

그러나 condition이 여러 스레드에 의해 설정된다면 제대로 된 동작을 위해서는 synchroniztion이 필요합니다.

스레드가 waiting 동작을 멈추는 것이 꼭 condition이 true가 되는 것을 의미하는 것은 아니기 때문에 몇 가지 더 잘못된 부분이 있습니다:

  • 거짓된 wakeup을 받을 수 있습니다(스레드가 특별한 신호를 전달받지 않고 waiting상태로부터 깨어나는 것을 의미합니다) 혹은
  • condition이 true로 설정되었는데 waiting스레드가 깨어날 때 쯤에 제 3의 스레드가 condition을 다시 false로 변경하는 상황(그리고 monitior를 다시 얻는)

이러한 경우들을 해결하기 위해서 필요한 것은 항상 아래 코드를 변형해서 사용하는 것입니다:

synchronized(lock){
    while(!condition){
        lock.wait();
    }
}

Synchronization에 얽매이지 않고 java.util.concurrent 패키지가 제공하는 개념들로 해결하면 더욱 좋겠네요.

  • 2016년 07월 18일에 작성됨

로그인이 필요한 기능입니다.

Hashcode는 개발자들을 위한 무료 QnA사이트 입니다. 작성한 답변에 다른 개발자들이 댓글을 작성하거나 좋아요/싫어요를 할 수 있기 때문에 계정을 필요로 합니다.
► 로그인
► 계정만들기
Close