所以我有这个简单的线程,每秒都会用新的时差来更新我的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毫秒,这就是它落后的原因?
提前致谢
答案 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);
}