准确的Thread.sleep用于简单的时钟应用?

时间:2013-10-21 05:18:18

标签: java multithreading concurrency

我有一个简单的时钟线程,每秒更新一次。为了实现这一点,我使用Thread.sleep(1000)每1秒调用一次工作类,但是,时钟似乎比我的计算机时钟稍微快一点。有没有办法使睡眠时钟正常化,以便它能在一秒钟内完全唤醒,与我的电脑时钟相同?

2 个答案:

答案 0 :(得分:2)

根据JavaDoc:

,这应该是预料之中的
  

导致当前正在执行的线程进入休眠状态(暂时停止   执行)指定的毫秒数,受制于   系统定时器和调度程序的精度和准确性。线程   不会失去任何监视器的所有权。

你能做什么,可能是睡得少,比如400毫秒,然后检查时间是否有所改变。

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

编辑:根据您的评论,您可以这样做:

long initTime = System.getTimeinMillis();
while(true)
{
      Thread.sleep(200);
      if((System.getTimeInMillis() - initTime) >= 1000)
      {
          initTime = System.getTimeInMillis();
          //Update your timer.
      }
}

答案 1 :(得分: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等中使用。