随着线程速度的增加,丢失精度

时间:2013-06-14 19:58:49

标签: java

所以我有这个简单的线程,每秒都会用新的时差来更新我的TextBox。

try {
        Thread.sleep(1000);
    } catch(InterruptedException ex) {
        Thread.currentThread().interrupt();
    }

    editTextBox.setText(""+timeDifference);

但是我希望TextBox更快地更新,但保持相同的值。所以我的想法是将睡眠值降低到现在的1/4(250),为了保持我的输出相同,我也会将输出减少1/4,结果是:

try {
        Thread.sleep(250);
    } catch(InterruptedException ex) {
        Thread.currentThread().interrupt();
    }

    editTextBox.setText(""+timeDifference/4);

然而,第二个例子的输出大约落后10%。为什么是这样?我的过程的计算时间是否超过250毫秒,这就是它落后的原因?

提前致谢

2 个答案:

答案 0 :(得分:4)

Thread.sleep(250)并不意味着您的线程将在250毫秒后再次开始执行完全

当您睡眠线程时,其状态将传递给idle。当sleep结束时,它会传递给active,这意味着可以执行,但调度程序可能正在忙于执行另一个线程(或甚至在此之前选择其他线程执行。

再加上执行线程(更改环境)和可能的计时错误所需的时间,并且您有延迟。大多数变化虽然不是恒定的,但与睡眠时间无关,因此当睡眠时间很短时,差异相对较大。

最后,请记住Java不是实时系统,所以你不能指望时间遵循一个接近的“时间表”(因为缺少一个更好的词)。

答案 1 :(得分:3)

这个程序的问题是什么并不重要,因为你不应该从the Event Dispatch Thread.以外的线程调用Swing UI组件上的任何方法

相反,计时器线程应定期将任务传递给invokeLater()。该任务应该快速计算显示时间并设置文本框的文本属性。

Runnable task = new Runnable() {
  private long previous = System.currentTimeMillis();
  @Override
  public void run() {
    editTextBox.setText(String.valueOf(System.currentTimeMillis() - previous));
  }
};
while (true) {
  try {
    Thread.sleep(250);
  }
  catch (InterruptedException ex) {
    Thread.currentThread().interrupt();
    break;
  }
  SwingUtilities.invokeLater(task);
}