【问题标题】:Can a Thread sleep for less than half milli seconds in Java/ Other language?Java/其他语言中的线程可以睡不到半毫秒吗?
【发布时间】:2016-06-22 20:31:45
【问题描述】:

[编辑]:得到答案后,我明白它不是 Java 特有的,它也与操作系统调度程序有关,所以添加其他标签

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

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

但我在查看Thread class中的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(在实际情况下可能不是这种情况),这不到半毫秒,这意味着我的线程将根本不用等。

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

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

【问题讨论】:

  • 什么能保证线程准确唤醒?
  • 这个问题也得到了回答:因为没有主要操作系统的调度程序以小于 1 毫秒的间隔运行。而且由于线程调度是由操作系统完成的,Java 受到操作系统的约束。
  • 没有。大多数操作系统都有一个 +/- 15 毫秒(而不是纳秒)的系统计时器。
  • @Vishrant 是的。如果您查看Thread.sleep() 的 API 文档,它明确表示:Causes the currently executing thread to sleep (temporarily cease execution) for the specified number of milliseconds, subject to the precision and accuracy of system timers and schedulers.
  • 根据我的经验,少于 5 毫秒的睡眠会导致计时问题。

标签: java c multithreading operating-system


【解决方案1】:

您可以使用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();

【讨论】:

  • @jtahlborn 我不确定你的意思。它是一个名为LockSupport 的内置类,带有一个方法parkNanos 我添加了一个Javadoc。
  • 我特别喜欢他们承认parkNanos() 可能会在没有明显原因的情况下提前返回。
  • @Peter Lawrey On Win XP it might sleep for 16 ms (1/60th of a second) 为什么会这样,是基于操作系统的工作原理吗?无论如何我们可以将它降低到 16 毫秒以下吗?几个月前我发布了一个类似的问题,没有人能够回答它..
  • 你怎么能确定忙等待你的线程会等待确切的给定时间?您能否详细说明您将如何实现忙碌等待?
  • @user3437460 Win XP 使用 1/60 秒的时间片。一个复杂的问题是它可以在比这更短的时间内返回,但是System.currentTimeMillis() 的分辨率是 1/60 秒,因此很难确定它花了多长时间。提示:你可以使用System.nanoTime() 提示2:不要使用Win XP。 ;)
猜你喜欢
  • 1970-01-01
  • 2018-02-17
  • 1970-01-01
  • 1970-01-01
  • 2018-07-14
  • 1970-01-01
  • 2015-11-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多