线程睡眠(毫秒)精度



Thread.sleep(500)将挂起当前线程至少500毫秒我知道它可能略高于500,但永远不会低于500。现在1毫秒=1000000纳秒我想挂起当前线程500毫秒,即=500*1000000纳秒但当我运行以下代码时,它的睡眠时间有时会低于指定值(以纳秒为单位)。为什么会这样?以及如何睡眠至少500*1000000纳秒。

long t1=System.nanoTime();
    try{
        Thread.sleep(500);
    }catch(InterruptedException e){}
    long t2=System.nanoTime();
    System.out.println((t2-t1)+" nanoseconds");
    System.out.println((500*1000000-(t2-t1))+" nanoseconds");

有时输出是

499795328 nanoseconds
204672 nanoseconds

我知道它可能略高于500,但它永远不会低于500。

我不确定你是从哪里得到这个想法的。文档非常清楚地指出,它将"在指定的毫秒数内休眠,取决于系统计时器和调度器的精度"。

没有任何东西可以保证持续时间是绝对的最小值

如果你想更接近理想,你已经有一半的解决方案了,因为你正在计算持续时间还剩多少纳秒。要计算出还要睡多少毫秒,你可以将不足(在这种情况下为204672)除以一千,然后再睡一次。

事实上,您可能希望在一个循环中执行此操作,直到剩余时间为零。以下伪代码可能会起作用:

def sleepFor (ms):
    baseTime = System.nanoTime()
    remainingTime = ms
    while remainingTime > 0:
        Thread.sleep(remainingTime)
        nowTime = System.nanoTime()
        remainingTime = ms - (nowTime - baseTime) / 1000

或者,你可以简单地接受这样一个事实,即足够接近就足够好,因为你的误差似乎约为0.04%(约为百万分之400)。

API文档说时间是

取决于系统计时器和调度程序的精度和准确性

因此,它睡眠的确切时间还没有确定
话虽如此,如果线程在一毫秒的一半时间内开始睡眠,然后在指定毫秒的开始时醒来,那么它可以比预期少睡1毫秒,这是有道理的
如果您需要精确的计时,那么Thread.sleep可能是错误的工具,事实上,任何垃圾收集的语言都可能是错误工具。

在更精确的延迟或周期上运行代码的一种方法是使用ScheduledExecutitorService

相关内容

  • 没有找到相关文章

最新更新