2013-03-29 3 views
3

다음 코드는 SCJP6 책에이해 멀티 스레딩

class ThreadA { 
    public static void main(String [] args) { 
     ThreadB b = new ThreadB(); 
     b.start(); 

     synchronized(b) { 
      try { 
       System.out.println("Waiting for b to complete..."); 
       b.wait(); 
      } catch (InterruptedException e) {} 
      System.out.println("Total is: " + b.total); 
     } 
    } 
} 

class ThreadB extends Thread { 
    int total; 

    public void run() { 
     synchronized(this) { 
      for(int i=0;i<100;i++) { 
       total += i; 
      } 
      notify(); 
     } 
    } 
} 

윌 둘 스레드 A와 B로 교착 상태가 각각의 동기화 블록 (B에 대한 잠금이 이전 코드 원인)?

나는 뭔가를 놓치고 있지만 무엇인지 잘 모릅니다.

+0

시도해 보셨습니까? 이게 효과가 있니? 나는 교착 상태의 댓가를 치지 않을 것이다 –

+0

사이드 노트 :이 상황에서는 교착 상태가 있었고 전체 대기/통보 메커니즘은 완전히 쓸모없는 완전 실패였다. – Dariusz

+2

왜 -1입니까? 그것은 나에게 합당하게 보인다 : | –

답변

4

에 달려 있습니다. wait 방법의 문서에서

-

다른 스레드가 통지() 메서드 또는이 오브젝트의 notifyAll() 메소드를 호출 할 때, 현재의 thread를 대기시킵니다. 즉,이 메서드는 호출 대기 (0)를 수행하는 것처럼 동작합니다.

현재 스레드가이 개체의 모니터를 소유해야합니다. 스레드는 이 모니터의 소유권을 해제하고 notify 메서드 또는 notifyAll 메서드 호출을 통해 다른 스레드가이 개체 모니터에서 대기중인 스레드 스레드가 깨어날 때까지 기다립니다. 스레드 은 모니터의 소유권을 다시 확보 할 수있을 때까지 대기하고 실행을 다시 시작합니다. 당신은 두 가지 시나리오를 고려한다면

그래서, - ThreadA 객체에 대한 잠금을 얻을 경우

  • b 첫째, 그것은 계속 ThreadB의 원인이됩니다 잠금의 해제, 결과, 대기 그 일.
  • ThreadB이 먼저 잠금을 얻으면 잘 작동하고 잠금을 해제 한 다음 ThreadA이 시작됩니다. 다음으로 ThreadA은 객체 잠금 b을 기다려서 영원히 기다릴 수 있습니다. 다음
+0

좋은 대답입니다. 짧은, 바로 그 지점. 문서 인용. 다시 말하지만 다시 믿게하겠습니다.) – Dariusz

+0

실제로 사실이지만, 메인 스레드가 결코 완료하지 못할 수도있는 지점을 놓치게됩니다. – assylias

+1

@assylias : 그래, 나는 그것을 놓쳤다. 편집 및 위의 두 시나리오를 입력하는 동안 잡았어요. 이제 괜찮아. –

6

가장 가능성이있는 실행은 :이 b.start() 사이에 약간의 지연

  • 메인 쓰레드 따라서 b에 잠금을 획득 관리 실행되는 run 방법이며 synchronized 입사

    • 블록
    • 그런 다음 b (을 잠그는 )
    • 을 기다립니다.
    • run이 실행을 시작하면, 모니터를 사용할 수있는 (또는 매우 곧 사용할 수 있습니다)이 그것 메인 스레드가 완료
    • 기다리고 중지 할 수 있습니다 b 통지 끝나면 그래서이 synchronized 블록
    • 를 입력 할 수 있습니다.

    그러나, 스레드 스케줄링에 따라, run이 먼저 실행되는 경우 메인 스레드가 b.wait()에 영원히 기다릴 수 있다는 것은 불가능하지 않다.예를 들어 b.start() 뒤에 작은 Thread.sleep(100)을 삽입하여이 문제를 해결하려면 해당 동작을 관찰해야합니다.

    결론 : 생동감있는 문제가 발생할 수있는 냄새가 심한 코드입니다 (잠금이 사용 가능하므로 교착 상태가 아닙니다).

  • +0

    실행 순서 오류가 잘 발생하지만 실제로 질문에 대답하지 않았습니다. – Dariusz

    +0

    @Dariusz 당신은 무엇을 의미합니까? – assylias

    +0

    질문은 "교착 상태가 발생할 것인가?"입니다. 나는 그것이 OP가 알고 싶어하는 것 같아요. 기다리는 것이 자물쇠를 풀어 준다고 당신이 알고 있다는 것을 압니다 만, 그것은 곧바로 답이 아닙니다. 좋은 대답, 나 +1했습니다. – Dariusz