我正在使用Java完成一些任务。我在计时方面遇到了一些问题:我需要设置一个具有固定重复周期的计时器。我尝试了标准Timer
和TimerTask
以及ScheduledExecutor
,但两者都以近似方式工作,即如果我设置了40毫秒的间隔,则使用以下代码(for { {1}})
Executors
然后我尝试打印"时间"每次执行
m_executor = Executors.newScheduledThreadPool(5);
Runnable thread = new TheThread();
m_executor.scheduleWithFixedDelay(thread, 0, 40000000, TimeUnit.NANOSECONDS);
结果是这样的:
private static final class TheThread implements Runnable {
@Override
public void run() {
System.out.println(System.nanoTime()/1000000);
}
}
正如你所看到的,如果我正确理解xxxxxx300
xxxxxx345
xxxxxx386
xxxxxx428
...
函数是以随机间隔调用的,接近我指定的函数(40毫秒),但不完全是我指定的内容!
例如,当我使用C和Win32s时,我能够使用高度准确的nanoTime()
函数,并且每40毫秒调用一次回调函数:
CreateTimerQueueTimer()
你们有人能给我一些提示吗?
谢谢
修改
我尝试移动时间测量以避免打印时间。我也尝试使用xxxxxx300
xxxxxx340
xxxxxx380
...
,但不幸的是,时间在35到47毫秒之间变化(在方法中设置为40)。
我徘徊于人们如何制作软件如模拟器或类似的东西,需要精确的时间段遵守...: - )
编辑2
好的伙计......我可以改变这条路,但我想一个可能的解决方案,我想向您展示并向您询问,专家:)这个想法如何适用(和安全)< / p>
这里的问题是每隔X毫秒运行一些方法,比如40毫秒。这里的问题是关于Java计时器/计时,但是这个简单的解决方案呢?
scheduleAtFixedRate()
使用此解决方案,当我在等待public class MyEmulator extends Thread {
private long start = 0;
private long end = 0;
@Override
public void run() {
long exec_time;
start = System.nanoTime();
/*
* Do the emulator-loop
*/
end = System.nanoTime();
exe_time = (end - start)/1000000;
// wait with a whil() (40 - exec_time)
}
}
结束后打印经过的时间时,结果正好是40毫秒(没有小数,这不是重要的)。
你认为它是安全的,即真的是40毫秒吗?
由于
答案 0 :(得分:4)
我认为你无法以这种精确度在Java中管理它。与您的C / Win32解决方案不同,您的Java解决方案在具有多个线程(具有不同优先级)的JVM中运行,并且运行垃圾收集并获取资源。
话虽如此,我会尝试scheduleAtFixedRate()
方法,该方法定期执行。 scheduleWithFixedDelay()
将执行并在完成延迟一段固定时间后执行。因此,不考虑您的方法实际运行所花费的时间。