我使用以下循环(删除一些内容)作为游戏的主循环,但我无法让它减速到我想要的速度,它的运行速度大约是我预期的两倍。
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的循环时间,这很容易导致循环的运行速度是预期的两倍。正如其他人提到的,有更好的方法来控制时间。