我们广泛使用 Java ThreadPoolExecutor。具体来说,我们遵循 fork join 模式,构建一个可调用列表并在它们上使用 invokeAll() 的定时变体。我们只使用这些线程池来执行 I/O(非 CPU 密集型)操作,但是查看线程转储,我们看到这些特定线程消耗大量 CPU。查看 FutureTask.awaitDone() 的实现,我可以看到通过对 LockSupport.parkNanos() 的交错调用实现了忙等待策略。查看 parkNanos 本身的 JavaDoc,我看到这条评论“可以虚假返回..”,这让我想知道 awaitDone() 是否正在旋转并进而导致 CPU 过高。任何帮助将不胜感激!
问问题
344 次
2 回答
0
我看到这条评论“可以虚假返回..”
对于 aReentrantLock
和也是如此Condition#await
。您通常将await
orwait
与 while 循环相关联的原因之一是线程暂停的虚假性质。也就是说,因为我们不担心虚假唤醒 aCondition
你也不应该在这里担心它。
它确实会旋转,但并不忙。第一个循环通常很快就会暂停。
于 2015-10-19T18:26:01.473 回答
0
我认为 awaitDone 并不是“像忙等待一样”,因为它调用了 parkNanos。parkNanos 在概念上类似于 Object.wait():一个线程正在等待,但 CPU 可以同时处理其他事情。由于虚假唤醒而存在无限循环,但这些是操作系统问题,它们也不意味着积极的忙等待。
线程可能会在方法中花费大量时间(“挂钟时间”),但这不一定是 CPU 时间。我的建议是使用分析器,因为它们可以做出这种区分,并且可以帮助您找到真正的 CPU 瓶颈。
相关问题:
UNIX 中的 wall-clock-time、user-cpu-time 和 system-cpu-time 具体是什么?
于 2015-10-20T15:26:31.713 回答