【问题标题】:Indefinite Thread Optimization无限线程优化
【发布时间】:2012-05-18 14:44:09
【问题描述】:

如何编写一个无限期运行的线程而不需要像 while 这样的昂贵循环?

好像我不想要这样的东西

public void run() {

            while(true)
            {
                do Blah Blah Blah
                Thread.sleep(.....);

            }

        }

编写如此长时间运行的线程的任何优化方式。

提前致谢。

【问题讨论】:

  • 你为什么认为它昂贵
  • 我猜这样一个无限的while循环会阻塞你的CPU。不是吗?所以我认为它很昂贵。
  • 在工作时使用 CPU 时间并不昂贵。休眠线程会释放 CPU(因此成本不高)。
  • 如果你在中间睡眠很多,那么无限循环并没有什么问题。如果您可以无限期地睡觉并且只在某些信号下醒来,那将是最好的。否则尝试只检查是否有新工作,然后再次休眠。

标签: java multithreading optimization


【解决方案1】:

我发现while (true) { ... } 是实现普通无限循环的最简洁方式。我认为没有比这更紧凑或更具成本效益的方式了。

虽然有些人更喜欢for (;;) { ... },但我觉得它看起来很尴尬。

在成本方面,javac 将两者都编译为

public static void main(java.lang.String[]);
  Code:
   0:  ...
       ...
       ...
       goto 0

}

如果你确实希望循环是无限的,我看不到任何更有效的方法。


由于您的代码中有Thread.sleep,我还建议您查看java.util.Timerjava.util.TimerTask


如果你的循环尝试重复做某事,你是对的,从长远来看你可能会浪费 CPU 时间。特别是如果您碰巧有许多此类线程的实例。在这种情况下,我建议您研究观察者模式。让对象等待某事,聆听影响其尝试成功的可能性的对象。

【讨论】:

  • 不能挑剔您的答案,但我不确定 OP 是否与您有相同的 costly 想法。
  • 我也不是,但是这种类型的问题迫使我去猜测。
【解决方案2】:

您认为while(true)“昂贵”的方式是什么?您是否有任何证据表明这会影响您的表现?你认为哪种手术比它便宜?

请注意您的评论:

我猜想这样一个无限循环会阻塞你的 CPU。不是吗?所以我认为它很昂贵。

听起来您正在考虑整个循环,而不是while 部分。所以让我们看看你在 in 循环中做了什么:

do Blah Blah Blah
Thread.sleep(.....);

您明确地告诉线程休眠。当它处于睡眠状态时,它不会消耗 CPU 资源。所以不,这并不昂贵。诚然,如果你的睡眠时间很短并且你的“do Blah Blah Blah”很快,你会循环很多 - 但在这种情况下,你应该考虑增加睡眠时间。 (您还应该考虑其他方法,这些方法允许您向线程发出信号,表明您希望它彻底退出,并且即使在它处于睡眠状态时也这样做,而不必中断线程。)

您没有向我们提供有关您真正想要实现的目标的任何信息,但基本上使用while 在这里不是问题。想想您想要 循环的频率,以及它是否真的是一个简单的基于时间的值。例如,如果这个线程是用来处理工作的,那么也许你想要一个具有某种描述的生产者/消费者队列——当它有工作要做时,线程不需要休眠,但它不需要唤醒 直到有工作要做。当然,这只是一个示例 - 如果没有更多信息,我们真的无法提供更多建议。

【讨论】:

  • 是的,我添加了睡眠,这样我就可以释放 CPU。我真正想问的是,有没有更聪明的方法来做同样的事情。
  • @Aryan:如果你想一次又一次地运行相同的东西,循环是理想的。正如我在回答末尾所说的那样,如果不了解更多背景信息,我们真的无法给您太多建议。请给我们更大的图景,我们也许可以提出替代方案。鉴于您只告诉我们“do blah blah blah”,我们甚至没有关于循环体在做什么的提示。请阅读tinyurl.com/so-hints
  • 实际上我有一个客户端试图从服务器获取一些配置。如果服务器关闭,它会失败并进入睡眠状态。启动服务器是手动步骤。所以我不确定它什么时候会发生在一分钟或一天。所以我一直在寻找最有效的解决方案
  • @Aryan,听起来你最好有一些观察者。 (将此添加到我的答案中。)
  • 观察者实现的问题是服务器和客户端之间没有其他的通信方式。而这两个独立的实体只能以这种方式相互交互。
【解决方案3】:

由于我们在猜测您所定义的成本,我想我会告诉您我能想到的可能的成本

一个线程通常有一些与之关联的堆栈内存。对于许多应用程序(例如桌面/用户应用程序)而言,与线程相关的堆栈内存量并不是真正的问题。但是假设您正在开发一个服务器,该服务器必须处理来自众多用户的长期连接。并且假设对于每个连接的用户,服务器必须重复执行相同的任务(就像您可能在 while 循环中执行的操作一样)。使用每个连接/用户的线程来解决此解决方案可能会变得非常昂贵。因此,与其在线程上阻塞/休眠,不如从 ThreadPool 中请求一个线程来执行相同的任务,只要你有事件这样做,它通常会更有效。这可以大大提高内存使用率。我认为只要相对于可用内存量可以拥有大量线程,就可以考虑这种优化。

你可能不是这样,因为你说“无限期”,但这是我最近遇到的一个有趣的问题,所以我想我会喋喋不休。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-05-28
    • 2023-03-14
    • 1970-01-01
    • 1970-01-01
    • 2019-04-12
    • 1970-01-01
    • 2023-04-04
    • 1970-01-01
    相关资源
    最近更新 更多