2

如何以常规(!)间隔创建每秒执行约 10000 次的循环?

(从 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.1 毫秒。(情况并非如此ScheduledExecutorService

4

3 回答 3

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。

于 2013-01-06T13:18:10.063 回答
0

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

于 2013-01-06T13:21:11.497 回答
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/秒的最大速率推送。

于 2013-03-23T04:21:13.460 回答