2015-10-19 43 views
0

我们广泛使用Java ThreadPoolExecutor。具体来说,我们遵循一个fork连接模式,构建一个可调用列表并在它们上使用invokeAll()的定时变体。我们只使用这些线程池来执行I/O(非CPU密集型)操作,但是看着线程转储,我们看到这些特定线程消耗高CPU。查看FutureTask.awaitDone()实现,我可以看到采用对LockSupport.parkNanos()的交叉调用实现了忙等待策略。看看parkDanos本身的JavaDoc,我看到这个评论“可以虚假地返回......”,这让我怀疑awaitDone()是否正在旋转,从而导致高CPU。任何帮助将不胜感激!CPU对FutureTask.awaitDone的影响

+0

你检查了探查CPU活动? – lbalazscs

+0

我使用这里描述的这种技术来编织jstack和top的输出以查找有问题的线程。 http://www.boxjar.com/using-top-and-jstack-to-find-the-java-thread-that-is-hogging-the-cpu/ – RPJ

+0

分析器提供了许多模式的详细信息,而不仅仅是线程使用CPU,也是使用哪种方法。有免费的Java分析器,例如VisualVm和“Java Mission Control”。 – lbalazscs

回答

0

我看到此评论“可以返回不合逻辑的。”

同样是一个ReentrantLockCondition#await如此。您通常将awaitwait与while循环关联的原因之一是由于线程暂停的虚假性质。这就是说,既然我们不担心虚假的唤醒与Condition你也不应该在这里担心。

它确实做了,但它并不繁忙。第一个循环通常紧接着是暂停。

+0

park()'在获得许可方面“大部分成功”是可能的,因为我们可以说很多其他并发unparking线程吗? – RPJ

+0

另外,是否有可能叉式线程发生大量唤醒导致高CPU? – RPJ

0

我认为awaitDone并不是因为它叫做parkNanos而“忙 - 等待”。 parkNanos在概念上与Object.wait()相似:一个线程在等待,但CPU可以同时处理其他事情。由于虚假的唤醒造成无限循环,但这些都是操作系统问题,并且也不意味着处于活动状态的繁忙等待。

该线程可能会花费大量时间(“挂钟时间”),但这不一定是CPU时间。我的建议是使用探查器,因为他们可以做出这种区分,并且可以帮助您找到真正的CPU瓶颈。

相关的问题:

What specifically are wall-clock-time, user-cpu-time, and system-cpu-time in UNIX?

Unsafe.park vs Object.wait

How can I Monitor cpu usage per thread of a java application in a linux multiprocessor environment?