Java真正的固定时间间隔

Java real fixed time interval

我正在使用 Java 执行一些任务。我在计时方面遇到了一些问题:我需要设置一个具有固定重复周期的计时器。我尝试了标准 TimerTimerTaskScheduledExecutor,但两者都以近似的方式工作,即如果我设置 40 毫秒的间隔,使用以下代码(对于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
...

如您所见,如果我正确理解 nanoTime() 该函数是随机调用的,接近我指定的时间间隔(40 毫秒),但不完全是我指定的!

例如,当我使用 C 和 Win32s 时,我能够使用高度准确的 CreateTimerQueueTimer() 函数,并且每 40 毫秒调用一次回调函数:

xxxxxx300
xxxxxx340
xxxxxx380
...

我试图移动时间测量以避免打印时间。我也尝试使用 scheduleAtFixedRate(),但不幸的是周期在 35 到 47 毫秒之间变化(在方法中设置为 40)。

我想知道人们如何制作软件,例如模拟器或类似的东西,需要精确的周期遵守...:-)

我想到了一个可能的解决方案,我想向您展示并请教您,专家们:) 这个想法如何适用(和安全)

这里的问题是 运行 一些方法每 X 毫秒,比如 40 毫秒。这里的问题是关于 Java timer/timing,但是这个简单的解决方案呢?

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)
    }
}

使用这个解决方案,当我在等待 whilt() 结束后打印经过的时间时,结果恰好是 40 毫秒(没有小数点,这并不重要)。

您认为这安全吗,即真的是 40 毫秒吗?

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

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