2016-12-30 8 views
0

揮発性のブール値を使ってスレッドのアクションを停止/開始/再開するフラグとして機能するよう試みましたが、動作しません。永遠に続くだけで終わらない。これを正しく行う方法や私のコードがうまくいかない理由についての助けがあれば、大歓迎です。前もって感謝します。フラグを使用してスレッド内のアクションを再開するにはどうすればよいですか?

public class thread { 

    public static int i = 0; 
    private static Thread print = null; 
    private static printThread runnable = null; 

    public static void main(String[] args) { 
     runnable = new printThread(); 
     print = new Thread (runnable); 
     print.start(); 

     System.out.println("Starting"); 
     runnable.begin(); 
     if(i > 5) 
     { 
      runnable.terminate(); 
     } 

     i = 10; 
     runnable.begin(); 
     if(i > 15) 
     { 
      runnable.terminate(); 
     } 
    } 

    public static final void print() 
    { 
     System.out.println(i); 
     i++; 
    } 

    public static final class printThread implements Runnable { 
     private volatile boolean running = false; 

     public void terminate() { 
      running = false; 
     } 

     public void begin() { 
      running = true; 
     } 

     public boolean isRunning() { 
      return running; 
     } 

     public void run() { 
      while(true) 
      { 
       if(running) 
       { 
        print(); 
       } 

       else 
       { 

       } 
      } 
     } 
    } 
} 
+0

"うまくいかない"というのはむしろあいまいです。あなたの質問を編集して、プログラムの予想される動作を拡張してください。そして、[並行性](https://docs.oracle.com/javase/tutorial/essential/concurrency/)について実際に自分自身に知らせるべきです。 – Paul

+0

'terminate()'は決して呼び出されないことがあります。たとえば、メイン関数が 'i'が5になる前に本体を実行しました。 – Tsyvarev

答えて

1

whileループ実行は終了しません。スレッドの開始/一時停止/再起動/停止をシミュレートするために終了し、待機する2つの状態を導入できます。しかし、スレッドを一時停止しても実行されますが、whileループ内では異なるコードブランチが実行されます。それは動作しません。しかし

は、

public static final class printThread implements Runnable { 
    private volatile boolean waiting = false; 
    private volatile boolean terminated = false; 


    public void terminate() { 
     terminated = true; 
    } 

    public void pause() { 
     waiting = true; 
    } 

    public void restart() { 
     waiting = false; 
    } 

    public void run() { 
     while(!terminated) { 
      if(waiting) { 
       //the thread is paused 
      } else { 
       //the thread is running 
      } 
     } 
    } 
} 
1

以下のコードを参照してください。永遠に続くだけで終わらない。

スレッドのrun()メソッドでは、volatile boolean runningフィールドの値は見ていません。 @Antonが指摘するように、あなたのスレッドが終了したら、それは他のいくつかのフラグなしで再起動することはできない。しかし、

public void run() { 
     while(!running) { 
      print(); 
      // you might want a short Thread.sleep(10); here to stop the spinning 
     } 
    } 

:それはおそらくのようなものでなければなりません。彼の答えを見てください。

また、メインスレッドと印刷スレッドの間でiを共有しています。それは適切に共有できるように、またvolatileである必要があります。複数のスレッドでインクリメントしているので、そのためにAtomicIntegerを使用してください。

public static AtomicInteger i = new AtomicInteger(); 
... 
if (i.get() > 5) ... 
... 
i.set(10); 
... 
i.incrementAndGet(); 

他のコメントのカップル:

  • staticフィールドに注意してください。 printrunnableは、アクセスを制限するためにmain(...)メソッドの内部でのみ定義する必要があります。
  • クラスは大文字で始まるので、PrintThreadである必要があります。
  • 実際には、PrintThreadはスレッドではないため、PrintRunnableまたはそれ以上の値である必要があります。Printer
関連する問題