1

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

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

    editTextBox.setText(""+timeDifference);

但我希望 TextBox 更新得更快,但保持相同的值。所以我的想法是将睡眠值减少到现在(250)的 1/4,并保持我的输出相同,我还将输出减少 1/4,结果如下:

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

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

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

提前致谢

4

2 回答 2

4

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

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

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

最后,请记住这Java不是实时系统,因此您不能期望时间会遵循紧密的“时间表”(因为需要更好的词)。

于 2013-06-14T20:07:37.060 回答
3

这个程序的问题是什么并不重要,因为您不应该从除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);
}
于 2013-06-14T20:15:10.883 回答