如何使用常规(!)间隔创建一个每秒执行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
)
答案 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 /秒。