如何暂停 java 线程一小段时间,比如 100 纳秒?

新手上路,请多包涵

我知道 Thread.sleep() 可以使 java 线程暂停一段时间,比如某些毫秒和某些纳秒。但问题是这个函数的调用也会产生开销。

例如,如果我希望线程暂停 100 纳秒,我会调用 Thread.sleep(0, 100) 。这个过程的总成本是 invocation_cost + 100 nanosceonds ,这可能比我想要的要大得多。我怎样才能避免这个问题,并达到我的目的?

我需要这个的原因是我想离线进行模拟。我分析了任务的执行时间;现在我想通过在同一时间段内挂起一个线程来模拟这个执行时间。

谢谢!

原文由 JackWM 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 940
2 个回答

睡眠的粒度通常受线程调度程序的中断周期限制。在Linux中,这个中断周期在最近的内核中一般是1ms。在 Windows 中,调度程序的中断周期通常在 10 或 15 毫秒左右

如果我必须暂停线程的时间少于这个时间,我通常使用忙等待

编辑:我怀疑您会在 jrockit + solaris 上获得最佳结果。 Windows 框上的数字很糟糕。

 @Test
public void testWait(){
    final long INTERVAL = 100;
    long start = System.nanoTime();
    long end=0;
    do{
        end = System.nanoTime();
    }while(start + INTERVAL >= end);
    System.out.println(end - start);
}

原文由 qwerty 发布,翻译遵循 CC BY-SA 3.0 许可协议

对于模拟,我不会尝试实时模拟,因为这不会为您提供可重现的结果。即你不能测试你的模拟。

相反,我会使用数据驱动的模拟时钟,并尽可能快地运行所有内容。这为您提供了可重现的结果,并允许您比实时模拟更快(例如快 2 到 100 倍)


怀疑一个线程大约需要 10 微秒。尝试将线程暂停比这更短的时间是没有意义的。

要忙等待一小段时间,你可以试试。

 long start = System.nanoTime();
while(start + delay >= System.nanoTime());

注意:正如@EugeneBeresovsky 评论的那样,在你的机器运行了 292 年之后,这可能会溢出,所以你可以选择将其写成

while(System.nanoTime() - start < delay);

这将对少于 292 年的延迟罚款。您可以使用 System.currentTimeMillis() 来延迟更长的时间。

然而,即使这样也不可靠,因为 System.nanoTime() 在 Centos 5.x 上最多可能需要 300 ns,因此调用它两次将花费比 100 ns 更长的时间。此外,许多操作系统的分辨率仅为 1000 ns(1 微秒),因此无论您要寻找的延迟如何,此循环最多将等待 1 微秒。

相反,您可以做的是在一个未优化的短循环中忙于等待。

对于 100 ns 的延迟,我怀疑最好是忙于等待你正在等待的任何东西,而不是创建一个单独的忙循环。

原文由 Peter Lawrey 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题