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

Jac*_*kWM 27 java sleep nanotime method-invocation thread-sleep

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

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

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

谢谢!

qwe*_*rty 22

睡眠的粒度通常受线程调度程序的中断周期的约束.在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);
}
Run Code Online (Sandbox Code Playgroud)

  • 这些天你必须经常搜索一个核心CPU.它显然确实占用了几纳秒的CPU.如果您有替代方案可以解决问题,请发表评论 (6认同)
  • 你是否意识到这个循环占用100%的单CPU核心?这是一种等待/睡眠的反模式. (5认同)
  • 您可能应该在此答案中明确表示它确实会影响 CPU。 (2认同)

Pet*_*rey 13

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

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


怀疑一个线程大约需要10微秒.没有必要尝试暂停线程的时间更短.

忙着等一小段时间你可以试试.

long start = System.nanotime();
while(start + delay >= System.nanoTime());
Run Code Online (Sandbox Code Playgroud)

注意:正如@EugeneBeresovsky评论,在您的机器运行292年后,这可能会溢出,因此您可以选择将其写为

while(System.nanoTime() - start < delay);
Run Code Online (Sandbox Code Playgroud)

这将适用于不到292年的延迟.您可以使用System.currentTimeMillis()进行更长时间的延迟.

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

相反,你可以做的是忙于在一个非优化方式的短循环中等待.

对于100 ns的延迟,我怀疑忙于等待你正在等待的任何事情而不是创建一个单独的忙循环会更好.


Ent*_*ops 5

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