Thread.sleep(毫秒)精度

时间:2015-12-31 02:32:13

标签: java thread-sleep nanotime

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

2 个答案:

答案 0 :(得分:2)

  

我知道它可能只有500多,但它永远不会少于此。

我不确定那个的想法在哪里。 docs非常清楚地表明它会在指定的毫秒数内休眠,受制于系统定时器和调度程序的精度和准确度

没有任何保证持续时间是绝对最小值。

如果你想接近理想状态,你已经有了一半的解决方案,因为你计算出持续时间剩下多少纳秒。要计算出睡眠多少毫秒,你可以将差额(在这种情况下为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)。

答案 1 :(得分:0)

API docs表示时间

  

受系统计时器和调度程序的精确性和准确性的影响

所以没有定义它睡觉的确切时间 话虽如此,如果线程在一半毫秒内开始睡眠然后在指定的毫秒开始时唤醒,那么它就会有意义,然后它可以在最少1毫秒的时间内休眠。 如果你需要精确的计时,那么Thread.sleep可能是错误的工具,事实上任何垃圾收集语言都可能是错误的工具。

在更精确的延迟或句点上运行代码的一种方法是使用ScheduledExecutorService