1

したがって、TextBox を毎秒新しい時差で更新するこの単純なスレッドがあります。

try {
        Thread.sleep(1000);
    } catch(InterruptedException ex) {
        Thread.currentThread().interrupt();
    }

    editTextBox.setText(""+timeDifference);

しかし、TextBox の更新を高速化しながら、同じ値を維持したいと考えています。したがって、私の考えは、スリープ値を現在の値 (250) の 1/4 に減らし、出力を同じに保つために出力を 1/4 に減らすことでした。結果は次のようになります。

try {
        Thread.sleep(250);
    } catch(InterruptedException ex) {
        Thread.currentThread().interrupt();
    }

    editTextBox.setText(""+timeDifference/4);

ただし、2 番目の例の出力は約 10% 遅れています。どうしてこれなの?プロセスの計算に 250 ミリ秒以上かかるのでしょうか?

前もって感謝します

4

2 に答える 2

4

Thread.sleep(250)スレッドがちょうど250 ミリ秒後に再び実行を開始するという意味ではありません。

スレッドをスリープ状態にすると、その状態が に渡されidleます。がsleep終了すると、 に渡されますactive。これは、 を実行できることを意味しますが、スケジューラが別のスレッドの実行でビジー状態になっている可能性があります (または、その前に実行する別のスレッドを選択したことさえあります)。

それに加えて、スレッドを実行に戻すのに必要な時間 (環境の変更) とタイミング エラーの可能性があるため、遅延が生じます。その変化のほとんどは、一定ではありませんが、睡眠に費やされた時間とは関係がないため、睡眠時間が短いほど差は比較的大きくなります.

Java最後に、それはリアルタイム システムではないため、時間が近い「スケジュール」に従うことを期待できないことを覚えておいてください (より適切な言葉が必要です)。

于 2013-06-14T20:07:37.060 に答える
3

Event Dispatch Thread以外のスレッドから Swing UI コンポーネントのメソッドを呼び出すべきではないため、このプログラムの問題が何であるかは問題ではありません。

代わりに、タイマー スレッドが定期的に にタスクを渡す必要がありますinvokeLater()。そのタスクは、表示される時間をすばやく計算し、テキスト ボックスのテキスト プロパティを設定する必要があります。

Runnable task = new Runnable() {
  private long previous = System.currentTimeMillis();
  @Override
  public void run() {
    editTextBox.setText(String.valueOf(System.currentTimeMillis() - previous));
  }
};
while (true) {
  try {
    Thread.sleep(250);
  }
  catch (InterruptedException ex) {
    Thread.currentThread().interrupt();
    break;
  }
  SwingUtilities.invokeLater(task);
}
于 2013-06-14T20:15:10.883 に答える