我们广泛使用Java ThreadPoolExecutor。具体来说,我们遵循fork join模式,构建一个callables列表并在它们上使用invokeAll()的定时变体。我们只使用这些线程池来执行I / O(非CPU密集型)操作,但是查看线程转储,我们看到这些特定线程消耗高CPU。查看FutureTask.awaitDone()实现,我可以看到通过对LockSupport.parkNanos()的交叉调用实现了忙等待策略。看看JavaDoc for parkNanos本身,我看到这条评论“可以虚假地返回......”,这让我想知道awaitDone()是否正在旋转并反过来导致高CPU。任何帮助将不胜感激!
答案 0 :(得分:0)
我看到这条评论“可以虚假地返回......”
ReentrantLock
和Condition#await
也是如此。您通常将await
或wait
与while循环相关联的原因之一是由于线程挂起的虚假性质。也就是说,因为我们不担心用Condition
进行虚假唤醒,所以你也不用担心它。
它确实可以旋转,但它并不忙。第一个循环通常很快就会暂停。
答案 1 :(得分:0)
我认为awaitDone不是“忙碌等待”,因为它称之为parkNanos。 parkNanos在概念上类似于Object.wait():一个线程正在等待,但CPU可以同时处理其他事情。由于虚假的唤醒,无限循环在那里,但这些是操作系统问题,并且它们也不意味着忙着等待。
线程可能会在方法中花费大量时间(“挂钟时间”),但这不一定是CPU时间。我的建议是使用分析器,因为它们可以做出这种区分,它们可以帮助您找到真正的CPU瓶颈。
相关问题:
What specifically are wall-clock-time, user-cpu-time, and system-cpu-time in UNIX?
How can I Monitor cpu usage per thread of a java application in a linux multiprocessor environment?