使用Thread.sleep()限制的循环运行次数是预期的两倍

时间:2014-08-14 19:49:27

标签: java

我使用以下循环(剪掉一些东西)作为游戏的主循环,但我不能让它降低到我想要的速度,它的运行速度大约是我打算。

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造成损害。

2 个答案:

答案 0 :(得分:1)

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

LockSupport.parkNanos(TIME_PER_LOOP - loopTime);

但正如其他人所说,有更好的方法可以控制时间安排(例如ScheduledExecutorService)。

答案 1 :(得分:0)

每次执行分工

(TIME_PER_LOOP - loopTime) / 1000000l

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