【问题标题】:Is Thread.sleep() a waste of time for polling in Java?Thread.sleep() 在 Java 中进行轮询是浪费时间吗?
【发布时间】:2016-10-09 11:56:02
【问题描述】:

假设我有一个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) 以供电脑休息。

但是,我不确定这是否有助于计算机在能源使用方面或其他方面。在这种情况下睡眠方法是否完全浪费时间?一点好处都没有?

【问题讨论】:

  • 几个 cmets:首先,我希望你实现某种 listener,只要名称标签中有 change 就会调用它,而不仅仅是不断更新,即使可能没有变化。其次,调用Thread.sleep 仅仅意味着当前调用线程让步给任何其他线程。如果有另一个线程在等待,那么它不一定会节省任何 CPU 时间。
  • 如果这是一个 GUI 程序,你可能需要使用一些特殊的措施来从后台线程更新 UI 组件。
  • @TimBiegeleisen:Thread.sleep 将释放 CPU 至少指定的数量,即使没有其他线程想要做任何事情。因此,与“忙循环”相比,它确实节省了 CPU。
  • 当然可以节省 CPU 时间。
  • @eldo 也许其他人不知道?不过感谢您的意见。

标签: java multithreading listener sleep


【解决方案1】:

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/

【讨论】:

  • 一个sleep()调用可以用于实现调度(例如,每n毫秒执行一次逻辑。)但是它是否足够准确 i> 对于您的应用程序,取决于您的应用程序的需求、托管它的操作系统的功能,以及可能取决于其他应用程序在同一机器上所做的事情。您并不总是需要 RTOS 来托管实时应用程序,但您的实时要求越严格,它的帮助就越大。
【解决方案2】:

这并不能回答您的直接问题,但它确实有助于解决您问题的 XY 问题部分:

看起来你正在通过轮询来监听对象状态的变化:通过不断测试一个对象来查看它的状态是什么以及它是否改变了,这是一个坏主意,尤其是在为 事件编码时-驱动 GUI。更好地使用观察者模式并在状态更改发生时或如果发生时通知。这就是 Swing GUI 库本身的编写方式,您应该强烈考虑仿效它。

通知更改的一些方法是使用组件事件侦听器,它可以侦听 Swing 组件的更改,例如 ActionListeners、ChangeListeners、ItemListeners 等。侦听非 Swing 组件项的另一种方法是使用 SwingPropertyChangeSupport 和 PropertyChangeListeners 并以此方式创建类的“绑定”属性。这通常用于非 GUI 模型类。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-10-23
    • 1970-01-01
    • 2021-11-24
    • 2011-05-01
    • 2014-11-30
    • 1970-01-01
    • 2020-05-18
    • 2017-02-14
    相关资源
    最近更新 更多