Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 简单时钟应用程序的精确线程睡眠?_Java_Multithreading_Concurrency - Fatal编程技术网

Java 简单时钟应用程序的精确线程睡眠?

Java 简单时钟应用程序的精确线程睡眠?,java,multithreading,concurrency,Java,Multithreading,Concurrency,我有一个简单的时钟线程,每秒更新一次时间。为了实现这一点,我使用了Thread.sleep(1000)每1秒调用一次worker类。然而,时钟似乎比我的计算机时钟运行得稍快。有没有办法使睡眠时钟正常化,使它能在一秒钟内完全醒来,与我的计算机时钟一样?根据 导致当前正在执行的线程休眠(暂时停止 执行),以指定的毫秒数为准 系统计时器和调度程序的精度和准确性。线 不会失去任何监视器的所有权 你可以做的是少睡,比如说400毫秒,然后检查时间是否改变 或者,您可以每秒使用一次和一次触发事件,并更新您的时

我有一个简单的时钟线程,每秒更新一次时间。为了实现这一点,我使用了
Thread.sleep(1000)
每1秒调用一次worker类。然而,时钟似乎比我的计算机时钟运行得稍快。有没有办法使睡眠时钟正常化,使它能在一秒钟内完全醒来,与我的计算机时钟一样?

根据

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

你可以做的是少睡,比如说400毫秒,然后检查时间是否改变

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

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

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

这个想法是去睡觉,醒来(可能是过早的),并再次检查时间去睡觉

在系统负载较重的情况下,计时器线程不会得到调度,线程可能不会从睡眠中醒来,从而导致时钟超时

但只要有可能,总是要显示正确的时间

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

以下是我为自己写的东西:

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

您是否使用System.currentTimeMillies()来执行?无法保证它不会比您的计算机运行得慢(在负载下)你不能依赖
睡眠
来保证准确性。除非你是在实时操作系统上运行。不久前,我看到了一个简单的修复方法,每次它醒来时都检查currentTimeMillies(),并且有一个不同的睡眠时间。但我再也找不到这个例子了?@Yonk:我已经更新了我的回答。这类似于我的第一个建议。@Yonk请记住,即使是
currentTimeMillies()
也不总是100%准确。我不会用这样的循环来绕开这个问题:如果睡眠1000毫秒不准确,那么睡眠200毫秒也不太可能准确。现在您已经多次引入该错误…@StevenSchlansker:这就是为什么我建议使用
计时器的原因。