2011-01-16 12 views
3

私はマルチスレッドプログラミングを開始しています。私は私のプログラムに文字 ' - 'と '+'を交互に表示したいですが、そうではありません。私の仕事は​​というキーワードを使用することです。限り私が持っている: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)); 
     } 

    } 

} 

EDIT:私も代わりにrunメソッドでforループをThread.sleepをテストします。

答えて

5

FunnyStringGenerator.next()であなたの​​ブロックが正常に動作しています。 '+''-'を交互に返します。

あなたはThreadToGenerateStr.run()で競合状態を持っているしかし:

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

これは同等です:

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

問題が発生します。gen.next

  • スレッド1つのコールを( )、 ' - 'の結果を得る
  • スレッド2はgenを呼び出します。 ' - '
'+'
  • スレッド2つの通話System.out.print()、書き込み、 '+'
  • スレッド1つの通話System.out.print()を書くの結果を得て、次の()

    「+」と「 - 」が逆の順序で書き込まれます。

    は例えば、様々な回避策があります。

    • コール(dogbaneの答えのように)単一​​ブロック内の両方gen.next()とSystem.out.print()
    • はGENを行います。 next()返すのではなくストリームに文字を書き込む
    • gen.next()を共有してBlockingQueueに追加し、このキューから文字を取り出して印刷する専用のI/Oスレッドを作成します。
  • 3

    代わりの方法を同期するのは、次の操作を行います

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

    は、あなたがそれを印刷する前に、別のスレッドがcの値を変更できないように同期ブロック全体print文をラップする必要があります。二つの文のように、それの

    思う:

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

    各文字の印刷には2つのスレッドを使用し、この待機と通知の概念を使用してください。

    +0

    なぜかダウン投票を教えてください。 –