在Java/其他语言中,线程的睡眠时间能否少于半毫秒?

在Java/其他语言中,线程的睡眠时间能否少于半毫秒?,java,c,multithreading,operating-system,Java,C,Multithreading,Operating System,[编辑]:在得到答案后,我明白了它不是Java特有的,它也与OS调度器相关,所以添加了其他标记 在Java中,线程是否可以休眠一纳秒 当然,在看了线程api之后,我们可以在睡眠方法中传递纳秒,答案可能是肯定的 但我在中查看了sleep方法的实现/来源后表示怀疑,即: public static void sleep(long millis, int nanos) throws InterruptedException { if (millis < 0) { thro

[编辑]:在得到答案后,我明白了它不是Java特有的,它也与OS调度器相关,所以添加了其他标记

在Java中,线程是否可以休眠一纳秒

当然,在看了线程api之后,我们可以在睡眠方法中传递纳秒,答案可能是肯定的

但我在中查看了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);
}
公共静态无效睡眠(长毫秒,整数纳米)
抛出中断异常{
如果(毫秒<0){
抛出新的IllegalArgumentException(“超时值为负”);
}
如果(纳米级<0 | |纳米级>999999){
抛出新的IllegalArgumentException(
“纳秒超时值超出范围”);
}
如果(纳米>=500000 | |(纳米!=0&&millis==0)){
米利斯++;
}
睡眠(毫秒);
}
现在,根据逻辑,如果经过的纳秒超过半毫秒,它将增加毫秒
1
。但这听起来不合逻辑,假设我写了一个代码,其中一个线程正在等待,比如说,40000纳秒(在实际场景中可能不是这样),这不到半毫秒,这意味着我的线程根本不会等待

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

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

您可以使用

然而,这与睡眠不同(它不可中断),它所做的只是将请求传递给操作系统。例如,在Windows 8上,即使是
Parknos(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 */ }
long end=System.nanoTime()+延迟;
while(System.nanoTime()
或者如果你想稍微友好一点

while (System.nanoTime() < end) 
     Thread.yield();
while(System.nanoTime()
什么能保证线程准确唤醒?这个问题也得到了回答:因为没有哪个主要操作系统的调度程序的运行间隔小于1ms。而且,由于线程调度是由操作系统完成的,所以Java受操作系统功能的约束。大多数操作系统都有一个+/-15毫秒的系统定时器(这比纳秒还多)。@Vishrant是的。如果查看
Thread.sleep()
的API文档,它会明确指出:
导致当前执行的线程在指定的毫秒数内休眠(暂时停止执行),取决于系统计时器和调度程序的精度和准确性。
根据我的经验,少于5毫秒的睡眠会导致计时问题。@jtahlborn我不确定你的意思。这是一个名为
LockSupport
的内置类,有一个方法
parknos
我添加了一个Javadoc。我特别喜欢这样一个事实,他们承认
parknos()
可能会无缘无故地在时间之前返回。@Peter Lawrey
在Win XP上,它可能会睡眠16毫秒(1/60秒)
为什么,是否基于操作系统的工作方式?我们有没有办法把它降低到16毫秒以下?几个月前我发布了一个类似的问题,没有人能够回答。你如何通过忙碌的等待来确定你的线程将等待确切的给定时间?您能详细说明一下如何实现忙等待吗?@user3437460 Win XP使用的时间片为1/60秒。一个复杂的问题是,它可以在比这更短的时间内返回,但是
System.currentTimeMillis()
的分辨率是1/60秒,这使得很难确定它花费了多长时间。提示:您可以使用
System.nanoTime()
提示2:不要使用Win XP
while (System.nanoTime() < end) 
     Thread.yield();