在应用程序/线程中测量时间花费

5

我正在使用Java编写一个模拟程序,其中物体按照牛顿物理学的规律运动。可以对物体施加力,并且由此产生的速度使其在屏幕上移动。由于模拟的性质,物体移动是根据当前和上一次动画循环之间经过的时间间隔来离散进行的;例如:

public void animationLoop() {
  long prev = System.currentTimeMillis();
  long now;

  while(true) {
    long now = System.currentTimeMillis();
    long deltaMillis = now - prev;
    prev = now;

    if (deltaMillis > 0) { // Some time has passed
      for (Mass m : masses) {
        m.updatePosition(deltaMillis);
      }

      // Do all repaints.
    }
  }
}

如果动画线程被延迟,导致大量的时间流逝(经典案例是在Windows下点击并保持最小化/最大化会阻止重新绘制),则会导致对象移动的速度惊人。我的问题是:是否有一种方法可以确定所花费的时间是动画线程而不是壁钟时间,或者有没有人能够建议一个解决方法来避免这个问题?

我唯一的想法是通过某些上限限制 deltaMillis


3
对我而言,限制 Delta 值似乎是一个不错的解决方案。 - Jim Blackler
4个回答

6
你有没有考虑使用计时器代替循环操作?这样可以更有效地实现你的目标。
TimerTask tt = new TimerTask(){
  long prev = System.currentTimeMillis();
  public void run(){
    long now = System.currentTimeMillis();
    for (Mass m : masses) {
      m.updatePosition(now-prev);
    }
    prev = now;
  }
}

new Timer(true).schedule(tt, 1000, 1000) ;

使用这种方式,您至少可以保证更新对象之间有一些延迟,因此不会像while(true)循环一样连续进行多次重绘,如果线程被延迟,您将不会立即重新执行任务。来自文档的说明:“在固定延迟执行中,每次执行都相对于上次执行的实际执行时间计划。”


3
我发现对于这个问题,javax.swing.Timer.html 特别有帮助。这里有一个示例,模拟了球形粒子与容器壁之间的弹性碰撞。
附加说明:这个相关方法可能有助于将模型与视图分离。一个独立的线程模拟系统的演变,而视图以固定速率呈现模型的“快照”。
在任何情况下,我会限制速率以适应最慢的目标平台。

谢谢 - 我已经在使用计时器,但想要摆脱它,因为我担心某台机器无法跟上指定的帧率;即我希望机器决定帧率而不是强制规定。 - Adamski
我明白了,尽管我倾向于从最慢的目标平台的“渲染预算”角度过于狭隘地思考。我添加了一个相关的示例,可能会提供一些见解。@Jim Blackler的建议可能是最好的。 - trashgod
@oxbow_lakes:我很乐意;你能推荐一个链接吗? - trashgod

1

您可能会喜欢阅读这篇文章,标题为“Java:使用ThreadMXBean获取线程时间”。

基本上,有一个名为ThreadMXBean的类可以让您获取特定Thread中花费的时间。虽然我没有尝试过,但是从我提到的文章中的方法和示例看起来很有前途,所以我认为您将能够通过它实现您想要的功能。


0

我会使用动画库来进行动画,而不是重新发明轮子。以下是两个不错的选择:


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接