Java阻塞线程会占用更多的CPU资源吗?

18

我想问一下,当线程被阻塞时(例如等待锁定被另一个线程锁定的监视器),Java是否会利用更多的CPU资源?

我现在正在查看一个线程转储,其中一些线程被阻塞,因为它们正在等待锁定监视器,我不确定这是否是高CPU使用率的原因。

谢谢!

编辑(2011年5月6日):我忘了提到这种行为是否与Java SE 1.4.2相关。

4个回答

33

线程会消耗诸如内存等资源。阻塞/非阻塞线程会产生一次性成本。如果一个线程每秒阻塞/非阻塞数万次,这将浪费大量的CPU资源。

但是一旦线程被阻塞,无论它被阻塞多长时间,都不会有持续的成本。


根据@sjlee发布的答案,我了解到如果自旋锁与阻塞线程有关,则会导致CPU利用率增加。因此,您不认为声称阻塞线程始终是无成本的假设有点过于强硬了吗? - Vishal K
请原谅我,但我真的很想知道您对我的先前评论的看法。或者,任何关于这个主题的链接或指针都将是很好的! - Vishal K
1
@VishalK 如果线程阻塞的时间相对较长,例如几十毫秒,则阻塞线程的成本较低。但是,对于非常短的时间段,阻塞可能会产生很高的开销。 - Peter Lawrey
感谢Peter提供宝贵的意见。那么,这是否意味着对于非常短暂的阻塞线程,JVM会涉及自旋锁机制?是否有任何文章可以在JVM层面上为我提供深入的了解? - Vishal K
@VishalK 我会查看已记录的 ReentrantLock 源代码。 - Peter Lawrey
显示剩余2条评论

20

答案并不简单。有些情况下,进入阻塞状态的线程可能导致 CPU 利用率增加。

大多数 JVM 使用分层锁算法,其中包括一些针对短时间持锁的锁定机制,例如自旋锁。当线程尝试获取监视器并发现无法获取时,JVM 可能会将其放在循环中,并让线程尝试获取监视器,而不是立即切换上下文。如果在某个特定的尝试次数或持续时间之后,该线程未能获取锁(取决于具体的 JVM 实现),则 JVM 将切换到“fat lock”或“inflated lock”模式,并切换掉该线程。

正是在自旋锁行为中,您可能会承担 CPU 成本。如果您的代码持锁时间非常短且竞争激烈,则可能会看到 CPU 利用率明显增加。有关 JVM 使用各种技术来降低竞争成本的讨论,请参见http://www.ibm.com/developerworks/java/library/j-jtp10185/index.html


谢谢您的解释,Lawrey的回答让我有些疑问,而您回答得很好。 - gagarwa

4
不,被阻塞在监视器上的线程不会占用额外的CPU时间。

那些处于WAITING/TIMED_WAITING状态的线程怎么办? - Diego Ramos

2
暂停或阻塞的线程不会消耗任何CPU时间。

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