2011-01-16 2 views
3

지금 막 멀티 스레딩 프로그래밍을 시작합니다. 내 프로그램 쇼에 번갈아 '-'와 '+'문자를 사용하고 싶지만 그렇지 않습니다. 내 임무는 synchronized 키워드를 사용하는 것입니다. 나는 대신 실행 방법에 for 루프를 Thread.sleep 테스트 :Java의 간단한 멀티 스레딩 프로그램에서 이상한 문제가 발생했습니다.

class FunnyStringGenerator{ 

    private char c; 

    public FunnyStringGenerator(){ 
     c = '-'; 
    } 

    public synchronized char next(){ 

     if(c == '-'){ 
      c = '+'; 
     } 
     else{ 
      c = '-'; 
     } 

     return c; 
    } 
} 

class ThreadToGenerateStr implements Runnable{ 

    FunnyStringGenerator gen; 

    public ThreadToGenerateStr(FunnyStringGenerator fsg){ 
     gen = fsg; 
    } 

    @Override 
    public void run() { 
     for(int i = 0; i < 10; i++){ 

      System.out.print(gen.next()); 
     } 
    } 


} 

public class Main{ 


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

     FunnyStringGenerator FSG = new FunnyStringGenerator(); 

     ExecutorService exec = Executors.newCachedThreadPool(); 

     for(int i = 0; i < 20; i++){ 
      exec.execute(new ThreadToGenerateStr(FSG)); 
     } 

    } 

} 

편집 : 지금까지 내가이 있습니다.

답변

5

FunnyStringGenerator.next()에 대한 여러분의 synchronized 블록이 작동 잘. '+''-'을 교대로 반환합니다. 당신이 ThreadToGenerateStr.run() 경쟁 조건이 그러나

는 :

char c = gen.next(); // Synchronized 
System.out.print(c); // Not synchronized 

문제는 경우에 발생합니다 :

System.out.print(gen.next()); 

이에 해당합니다

  • 스레드 1 호출 gen.next (), '-'결과 얻기
  • 스레드 2 호출 gen. 다음(), '+'
  • '+'
  • 스레드 1 전화 System.out.print()를 작성 2 호출 System.out.print()가, 쓰기, 스레드의 결과 점점 '-'

그 결과 '+'와 '-'가 반대 순서로 기록됩니다.

는 예를 들어, 여러 가지 가능한 해결 방법이 있습니다

  • 전화 (개정 향풀의 대답과 같은) 하나의 synchronized 블록 모두 gen.next()와 System.out.print()
  • 이 세대를합니다. next() 반환하지 않고 스트림에 문자를 쓰십시오.
  • gen.next()가 공유 된 문자 BlockingQueue에 문자를 추가하고이 대기열의 문자를 가져 와서 인쇄하는 전용 I/O 스레드를 만듭니다.
3

대신하는 방법을 동기화, 이렇게 :

 synchronized (gen) { 
      System.out.print(gen.next()); 
     } 

당신은 당신이 그것을 인쇄하기 전에 다른 스레드가 c의 값을 변경할 수 있도록 동기화 블록에 전체 인쇄 문을 포장해야합니다. 두 문장으로 그것의

생각한다

char n = gen.next(); 
System.out.print(n); 
-1

각 문자를 인쇄 할 때 두 개의 스레드를 사용하고 대기 및 알림이라는 개념을 사용하십시오.

+0

왜 아래로 투표하십시오. –