使用Thread.sleep时,线程休眠时的CPU消耗

14
我有一个服务器程序,它会轮询数据库以获取新的请求。我希望这种轮询每1分钟执行一次,所以在程序while循环中设置了Thread.sleep()。问题是每当程序需要“休眠”时,CPU利用率就会急剧增加(约25-30%)。但奇怪的是,当程序没有休眠并忙于处理请求时,CPU利用率降至0.4%。
我在网上阅读了一些资料,发现Thread.sleep会影响性能,但我找不到任何可行的替代方案(Thread.wait需要在对象上进行通知,在我的情况下无用)。
当没有新请求时,主循环不做任何事情,以下是CPU利用率为25%时正在执行的所有操作:
-> 轮询 -> 没有新记录? -> 休眠 -> 重复

你要睡多久?while循环的剩余部分在做什么? - user207421
2
这很奇怪。你能否将其简化为一个行为与你描述相似的小程序,并在此处发布?至少,请向我们展示你的“sleep”循环的框架(使用实际代码)。 - NPE
请提供实际休眠的代码部分。 - Nico Huysamen
2
你确定没有使用 Thread.sleep(60) 来让程序休眠60秒,对吧?(这会导致程序只休眠60毫秒) - Eran
2个回答

11

检查各个CPU核心的CPU消耗情况。如果您正在使用四核机器,可能有一个线程正在暴走并占用了一个核心(25%)。这通常发生在线程处于紧密循环时。

您可以使用具有超时的Thread.wait(确实Timer类是这样做的),但我觉得这不会有任何区别。无论是Thread.sleep还是Thread.wait都会将线程的状态更改为not runnable。虽然它取决于您的JVM实现等,但在线程处于此种情况下,线程不应该消耗那么多的CPU。因此,我认为存在某些错误。

另一件事情是获取线程转储并查看线程在此发生时正在执行什么操作。在Linux上使用kill -3,或者如果您使用Windows,则在Java控制台窗口中使用ctrl+break。然后,检查转储到标准输出的线程转储。然后您可以确定线程实际上是否正在睡眠或执行其他操作。


5
更明确地说:当线程处于“非可运行”状态时,它们不会消耗任何CPU资源,即使只有一点点也不会。这并不取决于实现方式。 - defnull

5
许多人指出,Thread.sleep 应该并且实际上确实可以帮助大幅降低 CPU 使用率。
我在原问题中省略了某些事实,因为我认为它们不相关。
主线程是生产者,还有另一个异步运行的线程是消费者。结果发现,此线程上的 "sleep" 在一些奇怪的条件下没有被正确触发。因此,该线程上的循环从未睡眠。
一旦消除了这个 "sleep" 问题,我就仔细分析并意识到了问题所在。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接