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

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

例如,如果我想要一个线程暂停100纳秒,我调用Thread.sleep(0,100) 。 这个过程的全部成本是invocation_cost + 100 nanosceonds ,这可能比我想要的要大得多。 我怎么能避免这个问题,实现我的目的呢?

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

谢谢!

睡眠的粒度通常受线程调度程序的中断周期的约束。 在Linux中,这个中断周期在最近的内核中通常为1ms。 在Windows中,调度程序的中断周期通常约为10或15毫秒

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

编辑 :我怀疑你会在jrockit + solaris上获得最佳成绩。 窗户上的数字很糟糕。

@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); } 

对于模拟,我不会尝试实时模拟,因为这不会给您可重复的结果。 即你无法测试你的模拟。

相反,我会使用数据驱动的模拟时钟并尽可能快地运行所有内容。 这为您提供了可重复的结果,并允许您比实时更快地模拟(例如,快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的延迟,我怀疑忙于等待你正在等待的任何事情而不是创建一个单独的忙循环会更好。

 public static void busySleep(long nanos) { long elapsed; final long startTime = System.nanoTime(); do { elapsed = System.nanoTime() - startTime; } while (elapsed < nanos); } 

Thread.sleep()另一个问题是它不能保证在指定时间后唤醒。 睡眠线保证睡眠达到指定的纳秒/微秒,但不保证在此之后立即醒来。 既然你在谈论纳秒的内容,你可能想尝试Object.wait(long, int)

用上述方法我已经完全符合10纳秒的数量级。

做一个忙碌的等待,(通过这么多数字做什么都有一个while循环周期)。 在程序开始时,您可以计算执行此忙碌等待所需的时间,并将其增加或减少到达5纳秒

我发现object.wait变得毛茸茸这个频率也注意到繁忙的等待解决方案很可能是机器相关的因此为什么你应该在你的程序开始时有一个校准步骤