2016-05-03 17 views
1

私はタイマースレッドを設定しようとしています。タイマースレッドは、カウンタをインクリメントしてその結果を端末に出力します。タイマのデッドロックの問題

public class SecondCounter implements Runnable 
{ 
private volatile int counter; 
private boolean active; 
private Thread thread; 

public SecondCounter() 
{ 
    counter = 0; 
    active = true; 
    thread = new Thread(this); 
    thread.start(); 
} 

public int getCount() 
{ 
    return counter; 
} 

public void run() 
{ 
    while(active) 
    { 
     try { 
      Thread.sleep(1000); 
     } catch(InterruptedException ex) {ex.printStackTrace();} 

     synchronized(this) 
     { 
      System.out.print(++counter+" "); 
      try{ 
       notifyAll(); 
       wait(); 
      } catch(InterruptedException ex) {ex.printStackTrace();} 
     } 
    } 
} 

その後、私は整数になりますmessagePrinter(と呼ばれるクラス)内の別の方法を持って、新しいスレッドを作成し、そのint型の複数のカウントにあるときに表示するメインタイマースレッドを監視します。

public synchronized void messagePrinter(final int x) 
{ 
    Runnable mp = new Runnable() 
    { 
     public void run() 
     { 
      while(active) 
      { 
       synchronized(this) 
       { 
        try { 
         while(counter%x != 0 || counter == 0) 
         { 
          notifyAll(); 
          wait(); 
         } 
         System.out.println("\n"+x+" second message"); 
         notifyAll(); 
        } catch(InterruptedException ex) {ex.printStackTrace();} 
       } 
      } 
     } 
    }; 
    new Thread(mp).start(); 
} 

私は待機()とのnotifyAll()かなりが、私は待ち状態に入ると、デッドロックの原因となる両方のスレッドに結果を試してみましたが、すべての組み合わせをいじり試してみました。または、タイマースレッドはすべてのスレッド時間を奪い、カウントが現在何であるかを確認する機会をmessagePrinterに与えません。ここで

は、出力がどのように見えるかです:

1 2 3 
3 second message 
4 5 6 
3 second message 

私はタイマーはおそらくこの方法で目盛りあたり完全に1秒であることを時間に行くされていないことを認識していますが、運動のポイントでしたスレッド間で情報を渡す経験を得る私が間違っているつもりどこにいくつかの洞察力を与えるためにいくつかのスレッドの経験のケアと

public class Main2 
{ 
    public static void main(String[] args) 
    { 
     SecondCounter c = new SecondCounter(); 
     c.messagePrinter(3); 
    } 
} 

誰も:ここ

は私のメインのファイルですか?

EDIT:整数カウンタに整数カウンタを変換し、 "this"の代わりに "SecondCounter.this"で同期するようにmessagePrinterを変更しました。それは今働いている!とにかく、複数のmessagePrinterがある場合、約30回のループ "x秒メッセージ"を出力します。私はそれを修正することができると思う。

+0

アトミック整数 –

+1

あなた 'synchronized'セクションであることを「カウント」オブジェクトを変換'異なることにより、これを同期しています'オブジェクト。最初は 'SecondCounter'のインスタンスを使い、2つ目は作成した' Runnable'のインスタンスを使います。私はJavaの初心者ですが、後者の場合は 'synchronized(SecondCounter.this)'を使うべきです(と 'SecondCounter.wait' /' SecondCounter.notifyAll')。 –

+0

私はそれを試してみましょう、ありがとう! – Araganor

答えて

0
私はそれが今働いている

、ここに私の作業のコードは次のとおりです。

import java.util.concurrent.atomic.AtomicInteger; 

public class SecondCounter implements Runnable 
{ 
private volatile AtomicInteger counter; 
private boolean active; 
private boolean printed; 
private Thread thread; 

public SecondCounter() 
{ 
    counter = new AtomicInteger(0); 
    active = true; 
    thread = new Thread(this); 
    thread.start(); 
} 



public void run() 
{ 

    while(active) 
    { 
     try { 
      Thread.sleep(1000); 
     } catch(InterruptedException ex) {ex.printStackTrace();} 

     synchronized(this) 
     { 
      System.out.print(counter.incrementAndGet()+" ");  
      printed = false; 
      try{ 
       this.notify(); 
       this.wait(); 
      } catch(InterruptedException ex) {ex.printStackTrace();} 
     } 
    } 
} 

public synchronized void messagePrinter(final int x) 
{ 
    Runnable mp = new Runnable() 
    { 
     public void run() 
     { 
      while(active) 
      { 
       synchronized(SecondCounter.this) 
       { 
        try { 
         while(counter.get()%x != 0 || counter.get() == 0) 
         { 
          SecondCounter.this.notify(); 
          SecondCounter.this.wait(); 
         } 
         if(!printed) 
         { 
          System.out.println("\n"+x+" second message"); 
          printed = true; 
         } 
         SecondCounter.this.notify(); 
         SecondCounter.this.wait(); 
        } catch(InterruptedException ex) {ex.printStackTrace();} 
       } 
      } 
     } 
    }; 
    new Thread(mp).start(); 
} 

}

関連する問題