3

저는 Java의 동시성에 대해 배우 았으며 제작자 - 소비자 문제를 발견했습니다. 그것은 명백하게 표준이며 많은 곳에서 거의 동일한 대답을 보았습니다. 동기화의생산자/소비자 솔루션에 혼란 스러움 (동기화 설명)

public synchronized void put(int num){ 
    while (!empty) { 
     try{ 
      wait(); } 
     catch {} 
    } 

    buffer=num; 
    empty=false; 
    notify(); 
} 

public synchronized int take(){ 
    while (empty) { 
     try{ 
      wait(); } 
     catch {} 
    } 

    empty=true; 
    notify(); 
    return buffer; 
} 

나의 이해는 스레드가 모두 넣어해야하며 취할 수 없다는 것을 의미 객체 전체 잠금을 사용한다는 것입니다. 그러나 두 방법 모두 다른 방법을 기다립니다. 이것은 내가 혼란스러워하는 곳이다. 이것은 교착 상태를 만드는 것처럼 보인다. 스레드 A가 들어가면 while empty=false을 입력하면 대기합니다. 그러나 스레드 B는 동기화되어 테이크를 입력 할 수 없습니다. 그러므로 빈 것은 영원히 거짓이며 교착 상태가됩니다.

그러나 기본적으로이 답변을 본 횟수가 몇 번 주어지면 올바른 것으로 보입니다. 나는 무엇을 잘못 이해하고 있는가?

감사합니다.

답변

4

wait을 호출하면 메서드 입력시 획득 한 잠금이 해제됩니다. 따라서 A가 put을 입력하고 wait이라고하면 잠금이 해제되고 B는 take 내로 진행할 수 있습니다. javadoc에서

는 :

The current thread must own this object's monitor. The thread releases ownership 
of this monitor and waits until another thread notifies threads waiting on this 
object's monitor to wake up either through a call to the notify method or the 
notifyAll method. The thread then waits until it can re-obtain ownership of the 
monitor and resumes execution. 
+0

좋아, 그 확실히 일을 명확히하는 데 도움이됩니다. 그러나 B가 내부 테이크이고 notify()를 호출하면 A가 깨우지 만 A는 현재 내부에있는 메소드에 대한 잠금을 갖지 않습니다 (B는 테이크를 떠날 때까지 하나의 라인이 더 있기 때문에). 그러면 A가 잠자기 상태로 돌아가거나 실제로 기다리지 않고 기다리지 않습니까? – akroy

+0

@Akroy, 인용 한 텍스트 다음에 또 다른 문장이 있습니다. "스레드는 모니터의 소유권을 다시 얻을 수있을 때까지 기다렸다가 실행을 다시 시작합니다." 게시물에 추가했습니다. 이제 너는 내가 바라는 전체 그림을 가지고있다. – Tudor

+0

나는 이렇게 생각한다. 이것은 훨씬 더 명확 해지고있다! 마지막 설명 : 원래 상황에서 A가 대기 중이면 다른 제작자 C가 들어 와서 put을 기다렸습니다. 어떻게 작동합니까? B에게 통보하는 것이 A와 C 모두를 깨울까요? 또는 그것은 하나가 먼저 반응 한 경쟁 조건입니까? 정말 고맙습니다! – akroy