使用Thread.sleep()调节的循环运行频率是预期的两倍以上



我使用以下循环(删除一些内容)作为游戏的主循环,但我无法让它减速到我想要的速度,它的运行速度大约是我预期的两倍。

private void myLoop() throws InterruptedException {
    long timer = TimeUtils.getMillis();
    int achievedLoops = 0;
    long currTime = 0l;
    long loopTime = 0l;
    long lastTime = TimeUtils.getNano();
    while(!isRequestedToStop) {
        currTime = TimeUtils.getNano();
        loopTime = currTime - lastTime;
        lastTime = currTime;
        if(TimeUtils.getDeltaMillis(timer) > 1000) {
            timer += 1000;
            logger.debug(achievedLoops + " Loops");
            achievedLoops = 0;
        }
        achievedLoops++;
        if(loopTime < TIME_PER_LOOP) {
            Thread.sleep( (TIME_PER_LOOP - loopTime) / 1000000l);
        }
    }
}

睡眠的另一种实现,得到稍微好一些的结果(循环只运行1.9次):

while(loopTime < TIME_PER_LOOP) {
    Thread.sleep(1l);
    loopTime += 1000000l;
}

另一个选择:

while(loopTime < TIME_PER_LOOP) {
    Thread.sleep(1l);
    loopTime = TimeUtils.getNano() - lastTime;
}

为什么会这样?
还有其他的方法可以降低线程的速度吗?

我基本上可以不受控制地运行它,因为逻辑与定时步骤相关联,但我想减少循环的总运行次数,否则它对CPU造成损害的可能性很小。

LockSupport可以在指定的纳秒数内禁用线程调度。

LockSupport.parkNanos(TIME_PER_LOOP - loopTime);

但是正如其他人提到的,有更好的方法来控制时间(例如ScheduledExecutorService)

每次执行除法

(TIME_PER_LOOP - loopTime) / 1000000l

你截断了结果,睡眠时间比预期少了1ms(平均0.5ms)。给定4ms的循环时间,这很容易导致循环的运行速度是预期的两倍。正如其他人提到的,有更好的方法来控制时间。

相关内容

最新更新