使用 Thread.sleep 的线程处于休眠状态时的 CPU 消耗

2022-09-04 20:44:34


我有一个服务器程序来轮询数据库中的新请求,我希望这个轮询以1分钟的间隔完成,所以我在程序中设置了一个Thread.sleep()while loop。
问题是,每当该程序应该“休眠”时,CPU消耗就会急剧上升(即大约25-30%)。
矛盾的是,当程序不休眠并且忙于处理请求时,CPU消耗下降到0.4%。
我在网上阅读并发现与thread.sleep相关的性能命中,但我找不到任何可行的替代方案(Thread.wait需要对对象进行通知,我觉得这在我的场景中是无用的)

主循环(当没有新请求时)不执行任何操作,以下是CPU消耗为25%时正在完成的所有操作的框架

->民意调查
-> 没有新记录?
->睡眠
->重复


答案 1

检查单个 CPU 内核的 CPU 消耗量。如果您使用的是4核计算机,则可能有一个线程正在流氓并且正在消耗一个核心(25%)。这通常发生在线程处于紧密循环中时。

你可以使用超时(实际上类确实如此),但我敢打赌它不会有任何区别。并将线程的状态更改为 。虽然这取决于您的JVM实现等,但在这种情况下,线程不应该消耗那么多的CPU。所以我敢打赌,有一些错误在起作用。Thread.waitTimerThread.sleepThread.waitnot runnable

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


答案 2

正如许多人指出的那样,Thread.sleep应该而且实际上确实有助于大幅降低CPU使用率。
我从最初的问题中省略了某些事实,因为我认为它们不相关。
主线程是生产者,还有另一个线程异步运行,即消费者。事实证明,这个线程上的“睡眠”是在一些奇怪的条件下,没有被正确触发。所以那个线程上的循环永远不会沉睡。
一旦睡眠问题被消除,我就会继续仔细分析它,以意识到问题所在。