一个线程可以用Java /其他语言睡眠不到半毫秒吗?

时间:2016-03-08 18:26:40

标签: java c multithreading operating-system

[编辑]:得到答案之后我理解它不是特定于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(在实际情况下可能不是这种情况),这不到半毫秒意味着我的线程不会等待。

有人可以评论相同的和为什么这个设计决定等待毫秒而非纳秒秒

还能保证线程能够准确唤醒吗?

1 个答案:

答案 0 :(得分:9)

您可以使用LockSupport's parkNanos

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();