高频回路

时间:2013-01-06 13:15:51

标签: java

如何使用常规(!)间隔创建一个每秒执行10000次的循环?

continuous data acquisition from parallel port in Java的副本,但是那个很难找到并且没有回答而且很老了)

我查看了Thread.sleep(long millis)Thread.sleep(long millis, int nanos)但是Windows上的Oracle的J2SE虚拟机总是比我指定的时间长1个毫秒。此外,nanos字段似乎被四舍五入到下一整个毫秒(经过验证,这是在Thread.java的源代码中硬编码的。)

实验结果:

  • Thread.sleep(0)不睡觉(100%cpu)
  • Thread.sleep(1)平均睡眠时间为1.95毫秒
  • Thread.sleep(2)平均睡眠时间2.95毫秒
  • Thread.sleep(0, 0)不睡觉(100%cpu)
  • Thread.sleep(0, 1)平均睡眠时间为1.95毫秒

那么如何定期循环迭代次数甚至超过500次呢?

编辑:我略微放松了“常规”要求。如果一个延迟比另一个延迟短4倍(即抖动不是问题),只要最长延迟是确定性的且低于0.1ms,这不是一个大问题。 (ScheduledExecutorService

不是这种情况

3 个答案:

答案 0 :(得分:2)

我相信你正在寻找ScheduledExecutorService(参见用法示例)。

特别是

scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit)

Creates and executes a periodic action that becomes enabled first after the given initial delay, and subsequently with the given period; that is executions will commence after initialDelay then initialDelay+period, then initialDelay + 2 * period, and so on.

使用TimeUnit.MICROSECONDS。

答案 1 :(得分:0)

当Java中的时序循环时,永远不会使用Thread.sleep(long),因为这是一种非常不精确的循环方法。请尝试使用javax.swing.Timer。链接在这里。 http://docs.oracle.com/javase/tutorial/uiswing/misc/timer.html

答案 2 :(得分:0)

如果你可以正确地将核心固定在100%,那么使用它可以在亚微秒的间距内获得相当均匀的分布式事件。当然,如果你使用这个来达到最大吞吐率,那么用一个成本较低的定时调用替换System.nanoTime()是可取的。

long nanosBetweenMessages = getSpacing();
long lastSendTime = 0l;
while (true) {
   final long curTimeNanos = System.nanoTime();
   if (curTimeNanos - lastSendTime < nanosBetweenMessages) {
       continue;
   }
   lastSendTime = curTimeNanos;
   sendEvent();
   if (done()) {
       break;
   }
}

我刚刚注意到你的10k / sec要求......我目前正在使用sendEvent()方法进行大量计算,推动最大速率约为20k /秒。