[编辑]:得到答案之后我理解它不是特定于Java,它也与OS调度程序有关,所以添加其他标签
在Java中是否可以使线程休眠纳秒。
当然在看了Thread api后我们可以在睡眠方法中传递纳秒时,答案可能是肯定的。
但是我在查看Thread class中的睡眠方法的实现/来源后怀疑,这是:
public static void sleep(long millis, int nanos)
throws InterruptedException {
if (millis < 0) {
throw new IllegalArgumentException("timeout value is negative");
}
if (nanos < 0 || nanos > 999999) {
throw new IllegalArgumentException(
"nanosecond timeout value out of range");
}
if (nanos >= 500000 || (nanos != 0 && millis == 0)) {
millis++;
}
sleep(millis);
}
现在根据逻辑,如果传递的纳秒超过半毫秒,它将毫秒增加1
。但这对我来说听起来不合逻辑,让我说我已经编写了一个代码,其中我的一个线程正在等待一些40000 nano seconds
(在实际情况下可能不是这种情况),这不到半毫秒意味着我的线程不会等待。
有人可以评论相同的和为什么这个设计决定等待毫秒而非纳秒秒?
还能保证线程能够准确唤醒吗?
答案 0 :(得分:9)
LockSupport.parkNanos(400_000);
然而这与睡眠不同(它不可中断),它只是将请求传递给操作系统。例如,在Windows 8上,即使parkNanos(1)
也可能睡眠1毫秒。
正如biziclop指出的那样,Javadoc提到了
虚假地(即无缘无故地)回叫。
根据我的经验,这种情况很少发生,但确实发生了。
但是,你是对的,Thread.sleep()将始终睡眠至少1毫秒。在Win XP上,它可能会睡眠16毫秒(1/60秒)
还能保证线程能够准确唤醒吗?
使用实时操作系统。
我做的是,不是去睡觉而是忙着等。通过这种方式,我可以更精确地停留一段时间。如果在隔离的CPU上运行线程(在Linux中),则可以将变化减少到大约10微秒
忙碌等待的一个例子
long end = System.nanoTime() + delay;
while (System.nanoTime() < end) { /* busy waiting */ }
或者如果你想要稍微友好一点
while (System.nanoTime() < end)
Thread.yield();