Java实际固定时间间隔

时间:2015-04-26 12:52:11

标签: java timer high-resolution

我正在使用Java完成一些任务。我在计时方面遇到了一些问题:我需要设置一个具有固定重复周期的计时器。我尝试了标准TimerTimerTask以及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毫秒吗?

由于

1 个答案:

答案 0 :(得分:4)

我认为你无法以这种精确度在Java中管理它。与您的C / Win32解决方案不同,您的Java解决方案在具有多个线程(具有不同优先级)的JVM中运行,并且运行垃圾收集并获取资源。

话虽如此,我会尝试scheduleAtFixedRate()方法,该方法定期执行。 scheduleWithFixedDelay()将执行并在完成延迟一段固定时间后执行。因此,不考虑您的方法实际运行所花费的时间。