1

我有一个简单的时钟线程,每秒更新一次时间。为了实现这一点,我曾经Thread.sleep(1000)每 1 秒调用一次工人班,但是,时钟似乎比我的计算机时钟运行得稍快。有没有办法让睡眠时钟正常化,让它在一秒钟内准确地醒来,和我的电脑时钟一样?

4

2 回答 2

2

根据JavaDoc,这应该是意料之中的:

使当前执行的线程休眠(暂时停止执行)指定的毫秒数,取决于系统计时器和调度程序的精度和准确性。该线程不会失去任何监视器的所有权。

你可以做的,可能是少睡,比如 400 毫秒,然后检查时间是否发生了变化。

或者,您可以使用 aTimer并每秒触发一次事件并更新您的时间。

编辑:根据您的评论,您可以执行以下操作:

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

想法是入睡,醒来(可能过早)并再次检查时间入睡。

在繁重的系统负载下,您的计时器线程不会被安排并且线程可能不会从睡眠中唤醒,从而导致您的时钟停止时间。

但它总是尽可能地显示正确的时间。

一般建议:最大化睡眠以保持最少唤醒(每次唤醒涉及一次上下文切换)。

这是我为自己写的:

   /**
     * 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 和其他地方的所有计时器、pingers 等中都使用。

于 2013-10-21T09:18:37.583 回答