linux / java中精确的事件计时

时间:2014-01-08 04:13:25

标签: java asynchronous

我正在用Java编写一个游戏,在后台进行一些机器学习以进行程序生成,我希望它在n milliseconds之后简单地从后台训练例程中逃脱,以渲染帧并更新NPC等等上。

关键是n不能被高估,因为游戏需要在所有有能力的硬件上被帧锁定到16ms并且在lgwjl中渲染内容本身就是一种平衡行为。

问题在于System.nanoTime()似乎在我的环境中不起作用(它会导致超出预期的数小几个数量级; HPC定时器在我的经验中非常不稳定)。并且System.getCurrentTimeMillis似乎没有明确指定的舍入行为,这意味着它可能会高估近一毫秒,这是不可接受的。

有人知道是否有一个好方法吗?

1 个答案:

答案 0 :(得分:2)

这样做你会有很多痛苦。您所描述的本质上是上下文切换操作系统(或JVM,在Java的情况下)应该从需要直接使用中抽象出来。

相反,您应该有一个用于处理业务逻辑的线程,以及一个用于管理和更新显示的完全独立的线程。然后,这两个线程通过控制器进行通信,该控制器在其自己的线程中运行,或者在与业务逻辑线程相同的线程中运行,具体取决于数据传输的复杂性。这个概念称为Model-View-Controller pattern,而many, many articles已经写成了如何最好地实现它。

通过分离这些行为,您可以让业务逻辑连续运行而不需要中断,并且您的视图线程可以非常简单,基本上如下所示:

while(true) {
  long initTime = curTime();
  // this will refresh the GUI and also show any new data from the controller
  refresh(); 
  sleep(curTime()-initTime);
}

我认为,你的问题当然是我上面提到的这种神奇的sleep()方法。我将更新所花费的时间传递给它,以便它可以从总的理想睡眠时间中减去它,但是如何确保实际睡眠时间非常精确的问题更为复杂。

你说System.nanoTime()在你的环境中是不精确的,不幸的是,这对你来说很可能是一个破坏者。 System.nanoTime()将提供您的OS /处理器发布的最精细的经过时间数据,因此如果此方法未提供您需要的数据,您的计算机/ JVM可能无法提供粒度你需要。

主要的游戏/模拟开发人员面临着同样的问题,并且早已通过消除对精确帧更新时间的要求来解决它,因为它太复杂而无法以任何可靠的方式将处理时间与实际时间对齐(例如,假设操作系统暂停了你的程序几毫秒,这样处理下一帧所需的时间会超过允许的时间,你会做什么?)。

相反,游戏和模拟等可视化的一般目标是计算模型的最新状态,并允许视图尽可能查询新信息。请考虑下表:

| Time | Model | Slow View | Med. View | Fast View |
|    1 |     1 |         1 |         1 |         1 |
|    2 |       |           |           |         1 |
|    3 |     3 |           |           |         3 |
|    4 |       |           |         3 |         3 |
|    5 |     5 |           |           |         5 |
|    6 |       |         5 |           |         5 |
|    7 |     7 |           |         7 |         7 |
|    8 |       |           |           |         7 |
|    9 |       |           |           |         7 |
|   10 |    10 |           |        10 |        10 |
|   11 |       |        10 |           |        10 |
|   12 |    12 |           |           |        12 |
|   13 |       |           |        12 |        12 |
|   14 |    14 |           |           |        14 |
|   15 |       |           |           |        14 |
|   16 |    16 |        16 |        16 |        16 |

在这里,我们看到一个任意的时间单位(系统上可用的最高精度),一个尽可能快地计算给定时间状态的模型,以及尝试显示最多的时间的视图日期状态可用。视图可以运行得越快,直到模型的速度,视图将在视觉上更加平滑,如果视图运行得比这更快,它不是真正的问题,尽管它没有变得更平滑。但无论如何,从用户的角度来看,模型的状态是实时更新的。

这里的关键见解是让您的模型计算给定时刻的状态,无论该值是什么,而不是尝试使模型以任何类型的精确速率运行,这在共享时基本上是不可能的硬件