Thread.sleep()中的奇怪行为

2022-07-20 00:00:00 sleep java

我注意到Thread.sleep()有一些非常奇怪的东西(这最终会使我的游戏崩溃),我不知道问题可能是什么。我已连续运行以下方法两个小时,输出始终为100+-5;

public void gameLoop() {
    t0 = time();
    while (GameState.getInstance().getState() == GameCondition.RUNNING) {

        engine.update();
        sfx.play();

        t1 = time();
        delta = t1 - t0;

        gfx.render((int) delta);
        t0 = time();
        System.out.println(delta);
        sleep(100);
    }
}

现在,如果我运行完全相同的方法,但不是针对常量100进行睡眠,而是针对delta

进行睡眠
public void gameLoop() {
    t0 = time();
    while (GameState.getInstance().getState() == GameCondition.RUNNING) {

        engine.update();
        sfx.play();

        t1 = time();
        delta = t1 - t0;

        gfx.render((int) delta);
        t0 = time();
        System.out.println(delta);
        sleep(delta);
    }
}

现在输出为:

0

1

1

1

1

1

1

1

1

1

1

1

1

1

1

1

1

1

1

1

1

1

1

1

1

1

1

1

1

1

2

....
 After a minute
 571

我不知道我是太累了,犯了一个明显的错误,还是发生了一些非常奇怪的事情,这是我的睡眠。

private void sleep(long milliSeconds) {
    System.out.println();
    try {
        Thread.sleep(milliSeconds);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

编辑:问题在哪里?增量正在"泄漏",因为内部方法(在睡眠之前)几乎不使用时间(如sleep(100)测试所证明的)我期望增量非常精确,几乎没有波动,但它仍在不断增长。


解决方案

在您的循环中,增量计算包含以前休眠的时间,然后在这个新的增量时间内休眠。如果睡眠(或您的代码)曾经很慢(比如1ms,这是可能发生的),那么下次您的增量将增加1ms,因此您将睡眠2ms。

您的下一次迭代将至少是2ms,因为您上次只睡了2ms。如果睡眠或您的代码再次变慢(这将发生),那么您将在下一次睡眠3ms,以此类推。您正在累积由于您的增量而可能发生的所有缓慢,包括以前的睡眠时间和其中的任何错误。

相关文章