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