我想问一下,当线程被阻塞时,Java 是否会使用更多的 CPU 资源,即等待锁定当前被另一个线程锁定的监视器。
我现在正在查看一个线程转储,其中一些线程在等待锁定监视器时被阻塞,我不确定这是否是高 CPU 使用率的原因。
谢谢!
编辑(2011 年 5 月 6 日)我忘了提及此行为是否与Java SE 1.4.2相关。
我想问一下,当线程被阻塞时,Java 是否会使用更多的 CPU 资源,即等待锁定当前被另一个线程锁定的监视器。
我现在正在查看一个线程转储,其中一些线程在等待锁定监视器时被阻塞,我不确定这是否是高 CPU 使用率的原因。
谢谢!
编辑(2011 年 5 月 6 日)我忘了提及此行为是否与Java SE 1.4.2相关。
线程消耗诸如内存之类的资源。阻塞/解除阻塞线程会产生一次性成本。如果一个线程每秒阻塞/解除阻塞数万次,这可能会浪费大量 CPU。
但是,一旦线程被阻塞,无论它被阻塞多长时间,都没有持续成本。
答案不是那么简单。在某些情况下,进入阻塞状态的线程最终可能会导致 CPU 利用率。
大多数 JVM 采用分层锁定算法。这通常涉及诸如自旋锁之类的算法,尤其是对于短期持有的锁。当一个线程试图获取一个监视器并且发现它无法获取时,JVM 可能实际上将它置于一个循环中并让该线程尝试获取监视器,而不是立即将它的上下文切换出去。如果线程在一定次数的尝试或持续时间(取决于特定的 JVM 实现)后未能获取锁,则 JVM 将切换到“胖锁”或“膨胀锁”模式,在该模式下,它会在上下文中切换出线程。
您可能会因自旋锁行为而产生 CPU 成本。如果您的代码在很短的时间内保持锁定并且争用很高,那么您可能会看到 CPU 利用率明显增加。有关 JVM 用于降低争用成本的各种技术的一些讨论,请参阅http://www.ibm.com/developerworks/java/library/j-jtp10185/index.html。
不,在监视器上被阻塞的线程不会占用额外的 CPU 时间。
挂起或阻塞的线程不消耗任何 CPU 时间。