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

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

我现在正在查看线程转储,其中某些线程在等待锁定监视器时被阻止,我不确定这是否是导致高CPU使用率的原因。

谢谢!

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


答案 1

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

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


答案 2

答案并非如此简单。在某些情况下,进入阻塞状态的线程可能最终导致 CPU 使用率。

大多数 JVM 采用分层锁定算法。通常涉及诸如自旋锁之类的算法,特别是对于短时间保持的锁。当线程尝试获取监视器并发现它无法获取时,JVM 实际上可能会将其放入循环中,并让线程尝试获取监视器,而不是立即将其关闭上下文。如果线程在一定次数的尝试或持续时间(取决于特定的 JVM 实现)后未能获取锁,则 JVM 将切换到“胖锁”或“膨胀锁”模式,在此模式下,它会在上下文中切换出线程。

正是在自旋锁行为中,您可能会产生 CPU 成本。如果您的代码在很短的时间内保持锁定,并且争用很高,那么您可能会看到 CPU 利用率明显增加。有关 JVM 用于降低争用成本的各种技术的一些讨论,请参阅 http://www.ibm.com/developerworks/java/library/j-jtp10185/index.html