1

1 秒に 1 回時刻を更新する単純なクロック スレッドがあります。それを達成するために、Thread.sleep(1000)以前は 1 秒ごとにワーカー クラスを呼び出していましたが、時計はコンピューターの時計よりもわずかに速いようです。コンピューターの時計と同じように、スリープ クロックを 1 秒で正確に起動するように正規化する方法はありますか?

4

2 に答える 2

2

JavaDocによると、これは予想されるはずです。

現在実行中のスレッドを、指定されたミリ秒数だけスリープ (一時的に実行を停止) させます。これは、システム タイマーとスケジューラの精度と精度に依存します。スレッドは、どのモニターの所有権も失いません。

あなたができることは、たとえば 400 ミリ秒の睡眠時間を減らしてから、時間が変わったかどうかを確認することです。

または、 a を使用してTimer1 秒ごとにイベントを発生させ、時間を更新することもできます。

編集:あなたのコメントによると、次のようなことができます:

long initTime = System.getTimeinMillis();
while(true)
{
      Thread.sleep(200);
      if((System.getTimeInMillis() - initTime) >= 1000)
      {
          initTime = System.getTimeInMillis();
          //Update your timer.
      }
}
于 2013-10-21T05:22:57.387 に答える
0

アイデアは、寝て、(おそらく時期尚早に)目を覚まし、もう一度時間を確認して寝ることです。

システムの負荷が高いと、タイマー スレッドがスケジュールされず、スレッドがスリープから復帰せず、時計がずれることがあります。

しかし、可能な限り正確な時間を表示することが常に重要です。

一般的な提案: スリープを最大化して、ウェイクアップを最小限に抑えます (各ウェイクアップには 1 つのコンテキスト スイッチが含まれます)。

ここに私が自分のために書いたものがあります:

   /**
     * Put the calling thread to sleep.
     * Note, this thread does not throw interrupted exception,
     * and will not return until the thread has slept for provided time.
     *
     * @param milliSecond milliSecond time to sleep in millisecond
     */
    public static void sleepForcefully(int milliSecond) {
        final long endingTime = System.currentTimeMillis() + milliSecond;
        long remainingTime = milliSecond;
        while (remainingTime > 0) {
            try {
                Thread.sleep(remainingTime);
            } catch (InterruptedException ignore) {
            }
            remainingTime = endingTime - System.currentTimeMillis();
        }
    }

このタイプのロジックは、JDK やその他の場所のタイマー、ピンガーなどで使用されます。

于 2013-10-21T09:18:37.583 に答える