0

私はrun()メソッドでプライベート揮発性ダブル値を更新し続けるRunnable "NanoClock"クラスを持っています。Java:揮発性変数が更新されない(getおよびsetメソッドが機能しない)

このクラスには、double値を返すgetTime()メソッドもあります。別のクラス( "Master")はNanoClockクラスを構築しており、スレッドを作成し、start()メソッドを呼び出す。

これを実行した後、getTime()メソッドを何回か(遅れて)呼び出しますが、値は更新されません。私は間違って何をしていますか?

NanoClock.java:

public class NanoClock implements Runnable { 
    private volatile boolean running; 
    private volatile double time; 
    public NanoClock() { 
     time = System.currentTimeMillis(); 
    } 
    @Override 
    public void run() { 
     running = true; 
     while(running) { 
      try { 
       if(System.currentTimeMillis() > time) { 
        time = System.currentTimeMillis(); 
       } 
       //This returns the updated value continuously when commented out 
       //System.out.println("Time: " + String.format("%.6f", unix_time)); 
       Thread.sleep(2000); 
      } catch(Exception exc) { 
       exc.printStackTrace(); 
       System.exit(1); 
      } 
     } 
    } 
    public double getTime() { 
     return time; 
    } 
    public void end() { 
     running = false; 
    } 
} 

Master.java:

public class Master { 
    public static void main(String[] args) { 
     try { 
      NanoClock nClock = new NanoClock(); 
      Thread clockThread = new Thread(new NanoClock()); 
      clockThread.setPriority(10); 
      clockThread.start(); 
      //MY_ISSUE: This returns the same value every time 
      for(int a = 0; a < 10; a++) { 
       System.out.println("Time: " + nClock.getTime()); 
      } 
      //MY_ISSUE: This cannot stop the while loop - I tested it with 
      //the println in the NanoClock class. 
      nClock.end(); 
      System.out.println("Done!"); 
     catch(Exception e) { 
      e.printStackTrace(); 
      System.exit(1); 
     } 
    } 
} 
+0

runメソッド内で常にrunningをtrueに設定するので、whileループは決して止まらないでしょう... – home

+0

'new NanoClock()'はどういう意見がありますか? –

+0

@homeしかし、runメソッドは一度だけ呼び出されます。だから私は実行の値をfalseに変更するまでメソッドを終了し、スレッドを終了する結果を変更するまでwhileループ内にとどまるはずです...またはrunメソッド自体が連続して呼び出されていますか? @SotiriosDelimanolis私は 'new NanoClock()'がクラスコンストラクタを呼び出し、objetのインスタンスを作成してスレッドに変換できると考えました。私はこの練習をすでに何度か見てきました...それに何か問題がありますか? – AlpayY

答えて

1

でなければなりませんバックギャングに時間を守る。もう1つはnClockです。これはメインスレッドのフォアグラウンドでぼんやりと座っています。

nClock、他のスレッドでRunnableされている必要があります:

Thread clockThread = new Thread(nClock); // not new NanoClock() 

これは、全体のソリューションではないかもしれないが、それは正しい方向への大きな一歩である必要があります。

+0

それは、ありがとう!時々あなたは盲目です...これは私を助けてくれました、ありがとう! – AlpayY

0

System.currentTimeMillis()長いを返しますが、あなたは、精度の損失を引き起こす、二重に保管してください。メンバ時間(およびゲッタの戻り値の型)を長く変更すると、期待される結果が得られるはずです。

経験則として、時間単位で作業する場合は、ほとんどの場合、最も適切なデータ型です。浮動小数点数は正確な結果を格納するのには適していません。

+0

当初このコード行は何かをしました。私は小数点が必要なので、時間をunixtime形式に変換しました。これは問題ではありませんが、NanoClockでprintlnメソッドを使用すると正しい結果が得られます。私の問題は、run()は揮発性の時間変数を更新しないということです。 – AlpayY

+0

@AlpayY現在の時刻と時間変数を比較して暗黙のキャストが発生するため、これが問題の一部になることがあります。そして、私はあなたの状態が期待どおりにうまくいくかどうかはわかりません。他にも指摘しているように、コードには他にも問題があります。だから、私の投稿はあなたの問題のほんの一部でしかないかもしれません。 –

0

以下のコードに2秒かかる場合は、時間が変更されます。

//MY_ISSUE: This returns the same value every time 
for(int a = 0; a < 10; a++) { 
    System.out.println("Time: " + nClock.getTime()); 
} 

しかし、10回の反復を持つforループとsystem.outは1ミリ秒かかるので変更されません。

なぜ2秒ですか?あなたの実行可能コードにThread.sleepがあるからです。

Thread.sleep(2000); 

これは、次の更新が2秒で行われることを意味します。

そして、本当にミリ秒ではなくナノ時間が必要なので、System.currentTimeMillis()の代わりにSystem.nanoTime()を使用してください。


更新:私のマシンで

public static void main(String args[]) { 
    long start = System.currentTimeMillis(); 
    for(int a = 0; a < 10; a++) { 
     System.out.println("Iterating " + a); 
    } 
    long end = System.currentTimeMillis(); 
    System.out.println("Start = " + start); 
    System.out.println("End = " + end); 
} 

の検索結果を、開始時間と終了時間に差

Iterating 0 
Iterating 1 
Iterating 2 
Iterating 3 
Iterating 4 
Iterating 5 
Iterating 6 
Iterating 7 
Iterating 8 
Iterating 9 
Start = 1499592836298 
End = 1499592836298 

は、コードブロックは、その非常に高速に実行されたことはありません1ミリ秒もかかっていませんでした。タイミングによっては、1ミリ秒かかることがあります。 System.nanoTimeのにそれを変更する

()

public static void main(String args[]) { 
    long start = System.nanoTime(); 
    for(int a = 0; a < 10; a++) { 
     System.out.println("Iterating " + a); 
    } 
    long end = System.nanoTime(); 
    System.out.println("Start = " + start); 
    System.out.println("End = " + end); 
} 

結果、開始時刻と終了時刻の差があります。あなたの他のスレッドでRunnableは喜んでいるようにそれらの一つは、匿名new NanoClock()です:main()

Iterating 0 
Iterating 1 
Iterating 2 
Iterating 3 
Iterating 4 
Iterating 5 
Iterating 6 
Iterating 7 
Iterating 8 
Iterating 9 
Start = 1012518090518837 
End = 1012518091012960 
+0

ありがとう、私は質問を投稿したときにその間違いをしたようです...私はNanoClockのrun()でsleepを削除し、forループにThread.sleep(2000)を追加しました。しかし、私はいつも同じ価値を持っているので、問題は依然として続きます。 – AlpayY

+0

再び、forループは1ミリ秒もかかりません。 – Itherael

+0

ありがとうございました。視覚化は非常に便利でした!同時に存在するNanoClockの2つのインスタンスで私の問題が嘘をついたとしても、これはNanoClockクラスのさまざまなテスト方法を試してみたときの間違いでした。 – AlpayY

0
Thread.sleep(2000); 
System.out.println("Time: " + nClock.getTime()); 

forあなたはNanoClockののインスタンスを持っているsleep(2000)

+0

ありがとう!申し訳ありませんが、私は実際のプログラムでこれを持っていました。私は今これを変更して、NanoClockクラスのスリープを削除し、forループにsleep(2000)を追加しましたが、同じdouble値が得られます。すべての反復。 – AlpayY

関連する問題