2016-08-20 3 views
1

아래 코드에서 wait() -notify()를 사용하여 스레드 간 통신을 구현했으며 예상 출력을 제공합니다. 예상 출력 : 123456789 실제 출력 : 123456789스레드 신호 시퀀스

제 질문은 쓰레드 스케줄링이 jvm에 의존하기 때문에 항상 '주 스레드'가 첫 번째 실행 기회를 얻을 것이라는 보장이 있습니까? '자식 스레드'가 첫 번째 기회를 얻으면 notify() 신호가 손실되고 '주 ​​스레드'가 영원히 기다립니다. 어떻게하면 '주 스레드'가 항상 먼저 실행되는지 확인할 수 있습니다. 또한 아래 코드를 개선 할 수 있는지 확인하십시오.

package com.test.Thread; 

public class ThreadExample1 { 

    public static void main(String[] args) throws InterruptedException{ 

     ThreadChild1 lockingObj = new ThreadChild1(); 
     lockingObj .start(); 
     synchronized(lockingObj){ 
      for(int i=1;i<10;i++){ 
       System.out.println("Main "+i); 
      } 
      lockingObj.wait(); 
      System.out.println("Main got notified"); 

     } 

    } 

} 

class ThreadChild1 extends Thread{ 

    public void run(){ 
     synchronized(this){ 
      for(int i=1;i<10;i++){ 
       System.out.println("Child "+i); 
      } 
      this.notify(); 
      } 
    } 
} 

답변

3

자신이 언급 한 이유로 코드가 잘못되었습니다. 어떤 스레드가 먼저 나올지 확신 할 수 없습니다. 다른 것들이 잘못 될 수 있습니다 - 없이 wait가 깨어날 수 있습니다.

당신은 또한 당신이 무엇을해야하는지 설명 Javadoc for the wait method에 대해 읽을 수 있습니다

: 하나 개의 인수 버전으로

는 인터럽트와 가짜를 깨우는 가능 있으며,이 방법은 항상 사용되어야한다 루프 : 코드에서

synchronized (obj) { 
    while (<condition does not hold>) 
     obj.wait(); 
    ... // Perform action appropriate to condition 
} 

, 당신은 조건을 표현하는 부울 변수로 해결할 수는 "나는 통보했다"

public class ThreadExample1 { 

    public static void main(String[] args) throws InterruptedException { 
     ThreadChild1 lockingObj = new ThreadChild1(); 
     lockingObj.start(); 

     synchronized (lockingObj) { 
      for(int i = 1; i < 10; i++) { 
       System.out.println("Main " + i); 
      } 
      while (!lockingObj.haveNotified) { 
       lockingObj.wait(); 
      } 
      System.out.println("Main got notified"); 
     } 

    } 

} 

class ThreadChild1 extends Thread{ 
    private boolean haveNotified; 
    public void run(){ 
     synchronized (this) { 
      for (int i = 1; i < 10; i++) { 
       System.out.println("Child " + i); 
      } 
      haveNotified = true; 
      this.notify(); 
     } 
    } 
} 
+0

감사합니다. @ 에윈. 그것을 이해하고 바로 잡았다. – RoyalTiger

1

이것은 시스템에서 올바르게 작동하지만 다른 시스템에서는 의심스러운 부분이 적용될 수 있으므로 큰 도움이되지 않습니다. 스레딩 동작은 예측하기가 어렵거나 불가능합니다. 따라서 나는 최악의 시나리오에서 생각하고 싶다. 그리고 내가 가능한 깨는 상황 (방금 언급했듯이)을 생각해 낼 수 있다면 나는 그것이 작동 할 수 있도록 재 설계한다.

코드를 테스트하는 좋은 방법은 IDE에 중단 점을 추가하거나 가능한 경우 Verry 시간 소모적 인 작업/호출을 추가하거나 (실수가 아닌) 스레드를 일시적으로 일시 중지하여 중요한 순간에 스레드를 일시 중지하거나 일시 중지하는 것입니다 (항상 이상적은 아님). 게다가 거기에 확실한 유형의 테스팅을 확장 할 라이브러리가 있습니다.

나는 이것이 당신에게 올바른 방향으로 조금 도움이되기를 바랍니다.

+0

감사합니다 n247s .. 나는 당신의 제안에 따라 테스트를 시도하고 있습니다. 나는 이해했다. 스레드 동작은 실제로 예상하기가 매우 어렵 기 때문에 아마 혼란 스러울 것입니다. – RoyalTiger