假设我有一个nametag
,它是GUI程序中的UI组件。
nametag
将根据数据不断更改其文本。
如果用户更改了他/她的姓名数据,那么他/她将在nametag
。
对于此任务,我的代码如下所示:
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
while (true) {
String name = data.getName();
nametag.setText(name);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
由于0.1s
的反应时间对人们来说似乎是即时的,因此我将Thread.sleep(100)
包含在计算机中以便休息。
但是,我不确定这在能源使用方面是否有助于计算机。在这种情况下睡眠方法完全浪费时间吗?没有任何好处?
答案 0 :(得分:3)
Thread.Sleep
已被用于许多不应该用的东西。以下列出常见错误:
线程需要等待另一个线程完成
在这种情况下,传递给
Thread.Sleep
的除了无限之外的任何值都是正确的。您根本不知道其他线程何时将使用此方法完成。如果在Sleep返回后完成线程,则可能会出现同步问题。如果另一个线程在Sleep返回之前完成,那么线程会被不必要地阻塞一段时间,从而使多线程的好处变得有限或没有实际意义。在您测试过的控制环境中,它似乎总是有效;只需要一个繁忙的程序就可以使其失效:碎片整理程序,网络流量突然涌入,网络打嗝等等。线程需要每隔
n
毫秒执行逻辑如前所述,睡眠意味着放弃控制。当你的线程再次获得控制权时,线程无法解决;所以它不能用于周期性逻辑。
我们不知道为什么需要
Thread.Sleep
;但如果我们把它拿出来,应用程序就会停止工作这是有缺陷的逻辑,因为应用程序仍无法与
Thread.Sleep
一起使用。这实际上只是在特定计算机上解决问题。原始问题很可能是一个时间/同步问题,忽略它会将其隐藏Thread.Sleep
只会延迟问题并使其随机发生,难以重现。
来源:http://blogs.msmvps.com/peterritchie/2007/04/26/thread-sleep-is-a-sign-of-a-poorly-designed-program/
答案 1 :(得分:2)
这不能解答您的直接问题,但它确实有助于解决您问题的XY问题组件:
看起来你正在通过轮询来监听对象状态的变化:通过不断测试一个对象来查看它的状态以及它是否被改变,这是一个坏主意,特别是当编码事件时 - 驱动 GUI。更好地使用观察者模式并在发生状态时 通知 状态更改。这就是Swing GUI库本身的编写方式,你应该强烈考虑模仿它。
通知变更通知的一些方法是使用可以侦听Swing组件更改的组件事件侦听器,例如ActionListeners,ChangeListeners,ItemListeners等。监听非Swing组件项的另一种方法是使用SwingPropertyChangeSupport和PropertyChangeListeners,并以这种方式创建类的“绑定”属性。这通常用于非GUI模型类。