Health and tuning of ForkJoinPool
我正在调查使用ForkJoinPool的应用程序中的一些性能问题。我们一直在使用Dynatrace进行处理,并且有迹象表明某些阻塞操作的持续时间太长了。我在FJP文档或其他地方找不到足够的有关如何配置和监视我们的ForkJoinPools的信息。
在ForkJoinPools上下文中,并行性是什么意思?为不同线程池(阻塞/非阻塞)选择值的准则/最佳实践是什么?
如何监视和调整我的ForkJoinPool?我们正在使用提供一些计数器的ForkJoinPool.toString(),但是我无法在javadoc中找到有关如何使用此统计信息进行调整的足够信息。 getStealCount()被描述为"...。应该足够高以使线程繁忙,但是要足够低以避免线程间的开销和争用",这并没有真正的帮助。
toString()的示例
1 2 | [Running, parallelism = 48, size = 47, active = 0, running = 0, steals = 33195, tasks = 0, submissions = 0] |
据我所知,无法调整此"框架"。配置仅限于并行性,线程工厂,异常处理和备用线程(请参阅下文中的并行性)。
我在2011年撰写了有关F / J代码的评论。
我多次升级了评论,而不再浪费我的时间。
隐藏数量完全一文不值。
每个线程上都没有统计信息,因此,活动,运行,任务等都使您不了解框架内部发生了什么。这些"监视器"中的大多数是在最初的Java7首次亮相后几年才添加的。例如,对于每个线程,了解处理的总数方法,总的等待时间等,将使您了解每个线程的性能。但是,由于该框架添加/删除线程(请参阅下文中的并行性),因此永远不会发生。拥有这些监视器中任何一个的总计数并不能告诉您任何有用的信息。
当然,
join()仍然存在严重的阻塞(停顿)问题。如果可以使用CountedCompleter类,情况会更好。
并行是指初始线程数。当线程阻塞到最大数量时,该框架会超过此数目(java.util.concurrent.ForkJoinPool.common.maximumSpares(除非向后移植,否则Java8中可能不可用))。该框架根据内部规则添加/删除线程(由于它与发行版有关,因此您需要自己查看代码。)另请参见Interface ForkJoinPool.ManagedBlocker及其支持代码。