【问题标题】:Weird behavior in Thread.sleep()Thread.sleep() 中的奇怪行为
【发布时间】:2013-04-11 23:25:44
【问题描述】:

我注意到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();
    }
}

编辑:问题? delta 正在“泄漏”,因为内部方法(在睡眠之前)几乎不使用任何时间(正如 sleep(100) 测试所证明的那样)我希望 delta 非常精确,波动很小甚至没有波动,但它会不断增长。

【问题讨论】:

  • 我认为您的增量计算已关闭。基本上delta = t1 - t0; 正在计算循环游戏循环所花费的时间,从输出来看,大约是一毫秒。然后,您实际需要做的是从此值中减去 MAXIMUM 等待时间。例如,如果你想要 25fps,那么你需要像 delta = 40 - (t1 - t0); 这样的东西,它会给出 40 毫秒或更短的 MAXIMUM 增量,以保持平均 25fps...(不要忘记允许负值;))
  • 我知道,这只是我的测试设置,我确实按照您在我所有的游戏中提出的建议(其他两个游戏:D)。我在这里遇到的问题是睡眠的奇怪行为,它会泄漏。
  • 1) “我注意到Thread.sleep() 有一些非常奇怪的事情(最终导致我的游戏崩溃)” 如果这是一个 Swing/AWT 应用程序。重绘可能应该由java.swing.Timer 触发,此后就不需要sleep(n)。 2) 为了尽快获得更好的帮助,请发帖SSCCE
  • 我正在实现主动渲染docs.oracle.com/javase/tutorial/extra/fullscreen/rendering.html 直接在缓冲区策略支持的画布上绘图,因此禁用了 Swing/AWT 绘制调用。
  • 可能是日程安排问题。尝试稍微增加增量。任何少于 5-10 毫秒的时间都和完全不睡觉一样好

标签: java sleep


【解决方案1】:

在您的循环中,您的 delta 计算包含先前睡眠的时间,然后为这个新的 delta 时间睡眠。如果睡眠(或您的代码)一直很慢(比如 1 毫秒,这可能会发生),那么下次您的 delta 会长 1 毫秒,因此您将睡眠 2 毫秒。

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

【讨论】:

  • +1 在我之前就进入了 - GC 也可以使其“变慢”。无论哪种方式,睡眠时间都应该从增量中减去,而不是添加到增量中。
  • @Pescis 同意 GC 问题(实际上可能是罪魁祸首)。
猜你喜欢
  • 1970-01-01
  • 2011-01-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-06
  • 2012-09-01
  • 2012-02-02
  • 2013-10-23
相关资源
最近更新 更多