c-在Java/其他语言中,线程可以睡眠不到半毫秒



[Edit]:在得到答案后,我理解了它不是Java特有的,它也与OS调度器有关,所以添加了其他标签

在Java中,是否可以让线程睡眠一纳秒。

当然,在查看了Thread api之后,我们可以在睡眠方法中通过纳秒,答案可能是肯定的。

但我在Thread类中查看了sleep方法的实现/来源后表示怀疑,它是:

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(在实际场景中可能不是这样(,它不到半毫秒,这意味着我的线程根本不会等待。

有人能评论一下吗?为什么这个设计决定等待毫秒而不是纳秒?

还有什么可以保证线程准确地唤醒?

您可以使用LockSupport的parkNanos

LockSupport.parkNanos(400_000);

然而,这与睡眠不同(它是不可中断的(,它所做的只是将请求传递给OS。例如,在Windows8上,即使是parkNanos(1)也可能睡眠1毫秒。

正如biziclop所指出的,Javadoc提到了

调用错误地(也就是说,没有任何原因(返回。

根据我的经验,这种情况很少发生,但确实会发生。


然而,你是对的,Thread.sleep((将始终睡眠至少1毫秒。在WinXP上,它可能会睡眠16毫秒(1/60秒(

还有什么可以保证线程准确地唤醒?

使用实时操作系统。

我所做的,就是不去睡觉,而是忙着等待。这样我就可以更准确地停下来一段时间。如果你在一个独立的CPU上运行线程(在Linux中(,你可以将变化减少到大约10微秒

繁忙等待的示例

long end = System.nanoTime() + delay;
while (System.nanoTime() < end) { /* busy waiting */ }

或者如果你想对稍微友好一点

while (System.nanoTime() < end) 
     Thread.yield();

最新更新