Java线程 - CPU使用率

5

以下是我正在阅读的教科书中的一句引言:

"也就是说,每当一个线程需要执行大量迭代的循环时,在每个迭代中放置一个sleep()是一个好习惯 - 即使是短暂的睡眠时间,例如5毫秒,也可以将应用程序的CPU使用率从100%降低到> 1%"

我认为这是一个好习惯,但是,调度程序难道不正是这样做的吗 - 给thread1一点时间; 暂停thread1; 给thread2一点时间...等。我无法理解这种降低率,请有意者给我启示。

5个回答

5
你经常在更新程序中看到这种情况。这被称为忙等待,是一种不好的做法。
如果你有一个循环像这样做某些事情:
public void run() {
    while(running) {
        gui.render();
    }
}

当你其实并不需要时,你会消耗CPU。你需要一遍又一遍地渲染它吗?每秒100000次以上?不,你只需要大约30帧每秒。

public void run() {
    while(running) {
        gui.render();
        try { Thread.sleep(10); } catch(InterruptedException e) { /* we tried */}
    }
}

这将使你的帧率略低于100帧每秒,并且你最终会获得更好的性能。

对于处理器密集型的后台线程,您并不总是希望出现这种情况,因为您希望它们具有优先级。话虽如此,如果您的后台线程占用了所有CPU,那么您将如何处理进一步的输入(比如,我不知道,一个“取消”按钮,因为您没有意识到开始了那个耗时数小时的计算?)

因此,在您的线程中添加一个小的休眠时间可能是一个非常好的决定。


2
调度程序就是这样做的。
不同之处在于调度程序会妥善地执行它。这意味着它将有效地使用CPU,这就是为什么您会获得良好的CPU使用率。
我没有看到任何不好的地方。这只是意味着它正在工作。
当您让它休眠时,将会有更多的空闲时间,并且您将减少CPU使用率。如果出于某种原因这是您的目标,那么也可以这样做。
高CPU使用率并不会有害(除非您过热,这种情况下您有硬件问题)。
通常,当我处理多线程问题时,我实际上会针对高CPU使用率进行优化。这通常意味着问题在线程之间被平均分配,而我从CPU中获得了最大收益。
如果您只使用1%的CPU,那么它就不起作用,那么为什么要拥有如此好的计算机?您应该充分利用硬件。

1
Joshua Bloch的Effective Java第72条: 不要依赖于线程调度程序。它没有正确地执行。引用:“如果线程没有做有用的工作,它们就不应该运行。”和“线程不应该忙等待”。 - corsiKa
我从未说过你应该忙等。 "循环多次迭代"和忙等之间存在很大区别。如果迭代是有限的,我们希望它完成;如果是忙等(无限),那么我们可以让它休眠。 - Yochai Timmer

2

当你的程序进行数字计算(或其他cpu密集型任务)时,你希望它以100%的速度运行,对吧?

另一方面,如果你的程序正在等待输入,则应尽可能使用异步编程,而不是无限循环运行(异步=系统调用你)。


你说得对。这个没有提到。我明天会和老师讨论。 - nullpotent

0

算了吧。将CPU使用率限制在1%有什么好处?完全没有?

通常情况下,将CPU使用率降低100倍意味着将应用程序的速度降低相同的倍数。

你可能希望这样做是因为有其他更重要的线程,或者你可能想使用Thread.interrupt()停止此线程,但两者都可以通过其他方式实现。


嗯,它购买了同时使用其他程序的能力。大多数带有循环的线程不需要持续运行。它们可以从中受益。 - corsiKa
我可以同时运行许多其他程序。在Linux中,占用CPU资源的进程会内部降低优先级,所以我不太担心。此外,现在大多数计算机都有多个核心。 - maaartinus
无论如何,它都会占用整个核心。您无法直接控制应用程序中的优先级,如果通过操作系统进行控制,那也只是一个建议。这是繁忙等待的症状,是一个非常严重的性能问题。 - corsiKa
建议?无论你使用什么,都要使用真正的操作系统。很久以前,我在我的双核PC上运行了3-5个低优先级计算任务,持续了数周而不会真正打扰我。至于忙等待 - 大多数情况下是错误的,但在你之前没有人谈论过它。 - maaartinus
我无法想象一本初级的Java教材会以任何其他方式利用线程,而不是GUI循环(这是最常见的线程,它将具有任何类型的迭代,否则不会自行阻塞)。我的经验也是,初学者Java程序员(尤其是那些阅读教科书的人)使用非阻塞循环实现他们的GUI,导致无休止的渲染。难道没有其他人连接点来看教科书作者的意图吗?值得注意的是,OP实际上在我发布后将他接受的答案更改为我的答案。 - corsiKa
好的,你对这本愚蠢的教科书的解释可能是正确的。 - maaartinus

0

我从未听说过这样的做法,但它可能会导致CPU使用率大幅下降。这是因为调度程序为每个线程分配的时间“片段”非常小,因此与此相比,5毫秒是相当长的时间。

话虽如此,我看到你可以从这样减缓线程的地方受益:单核机器的响应能力。


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