2011-09-10 4 views
2

자바에서 라디오를 코딩 중이며 스트림을 재생할 수있는 스레드를 사용하고 있습니다. shouldPlay라는 변수가 true인지 확인하는 스레드의 실행 메소드에 while 루프가 있습니다. 플레이어를 실행합니다. 그런 다음 변수를 false로 설정하는 pause() 메서드가 있으며 자연스럽게 변수가 false 일 때 플레이어가 실행되지 않도록하고 싶습니다.스레드에서이 Java 루프가 작동하지 않는 이유는 무엇입니까?

class audiostream extends Thread { 

    private boolean shouldPlay = true; 

    @Override 
    public void run() { 
     while(true) 
     { 
      if(shouldPlay) 
      { 
       shouldPlay = false; 
       System.out.print("test"); 
      } 
     } 
    } 

    public void pause() { 
     shouldPlay = false; 
    } 

    public void play() { 
     shouldPlay = true; 
    } 

} 

스레드가 먼저 실행하면 내가 어떻게 할 것은, 그것은 (그것을 잘 수행) "테스트"를 인쇄해야합니다 : 나는 아래를 설정 한 방법의 작은 예제를 만들었습니다. 그런 다음 pause()를 실행하면 shouldPlay를 false로 설정하고 "test"를 출력하지 않아야합니다. 그러나 play()를 호출하면 shouldPlay를 true로 설정하고 테스트를 다시 인쇄해야합니다. 문제는 그것이 그렇게하지 않는다는 것입니다.

약 1/100의 시간이 걸립니다. 내가 여기에 문제가 있다고 가정하는 것은 play()와 pause()를 다른 스레드에서 "hang"하지 않고, 자식 스레드가 while 루프에 걸려 있고 play()를 호출하거나 pause() 부모로부터 변수는 그 루프 때문에 값을 변경하지 않습니까? 그렇다면 내가 무엇을해야하는지 모른다!

답변

4

추가 '휘발성'이

private volatile boolean shouldPlay = true; 
1

shouldPlayvolatile해야 수정 및 삭제하시기 바랍니다 것 - shouldPlay = false;

if(shouldPlay) 
{ 
    // shouldPlay = false; 
     System.out.print("test"); 
} 
1

당신은 대안으로 AtomicBoolean를 사용할 수있다.

0

Java 메모리 모델은 () 스레드와 동기화 할 경우 다른 스레드가 변경 한 내용을 스레드에 알립니다. Java 언어 사양 defines동기화-으로 다음과 같이

동기화 작업이 유도 다음과 같이 행동에 대한 관계와 동기화 정의 :

  • 모니터 m에 잠금 해제 작업을 동기화-로m에 대한 모든 후속 잠금 조치 (후속은 동기화 순서에 따라 정의 됨)
  • 휘발성 변수 (§8.3.1.4)에 대한 쓰기 v과 동기화됩니다. 이후 스레드는 동기화 순서에 따라 정의됩니다 (임의의 스레드에 의해 v).
  • 스레드를 시작하는 작업 은 시작하는 스레드에서 첫 번째 동작 인과 동기화됩니다.
  • 각 변수에 대한 기본값 (0, false 또는 null)의 쓰기 은 모든 스레드의 첫 번째 동작 인과 동기화됩니다. 변수를 포함하는 개체가 할당되기 전에 변수에 기본값을 쓰는 것이 약간 이상하게 보일 수 있지만 개념적으로 모든 개체는 프로그램의 시작 부분에 기본 초기화 된 값으로 만들어집니다.
  • 스레드의 마지막 동작 T1은 이 종료되었음을 감지하는 다른 스레드 T2의 동작을과 동기화합니다.T2T1.isAlive() 또는 T1.join()을 호출하여이를 수행 할 수 있습니다.
  • 스레드 T1 스레드 T2 인터럽트 경우 T1의한 인터럽트 동기화-으로 다른 스레드 (T2를 포함) 포인트 T2은 (던져진 InterruptedException를 구비하거나 Thread.interrupted 또는 Thread.isInterrupted를 호출하는 것에 의해) 중단 된 것으로 판단한다. 당신의 예에서

는 스레드 쓰기 shouldPlay하고 그 어느 것도하지 않는다 읽는 스레드하여 synchronized-with을 설정 실패. 따라서 읽기 스레드가 새 값을 알아 채는 지 여부는 지정되지 않습니다.

귀하의 경우, 해당 동기화를 설정하는 가장 쉬운 방법은 shouldPlay입니다.

관련 문제