我正在研究使用ForkJoinPool的应用程序中的一些性能问题。我们使用Dynatrace进行过处理,并且有迹象表明某些阻塞操作的持续时间太长了。我在FJP文档或其他地方找不到有关如何配置和监视我们的ForkJoinPools的足够信息。

  • 在ForkJoinPools的上下文中,并行性是什么意思?对于不同的线程池(阻塞/非阻塞)选择哪个值,准则/最佳实践是什么?
  • 如何监视和调整ForkJoinPool?我们正在使用提供一些计数器的ForkJoinPool.toString(),但是我无法在javadoc中找到有关如何使用此统计信息进行调整的足够信息。 getStealCount()被描述为“....应该足够高以保持线程繁忙,但又要足够低以避免线程间的开销和争用”,这实际上没有帮助。

  • toString()的示例
    [Running, parallelism = 48, size = 47, active = 0, running = 0, steals
    = 33195, tasks = 0, submissions = 0]
    

    最佳答案

    据我所知,没有办法调整此“框架”。配置仅限于并行,线程工厂,异常处理和备用线程(请参阅下文中的并行性)。

    我在2011年写了关于F/J代码的critique
    我已经多次升级了评论,而不再浪费我的时间了。

    偷窃计数完全是一文不值。

    每个线程上都没有统计信息,因此, Activity ,运行,任务等都不会为您提供有关框架内部正在发生什么的知识。这些“监视器”中的大多数是在最初的Java7首次亮相后几年才添加的。例如,对于每个线程,了解处理的总数方法,总的等待时间等,将使您了解每个线程的性能。但是,由于该框架添加/删除线程(请参阅下文中的并行性),因此永远不会发生。这些监视器中的任何一个的总数都不能告诉您任何有用的信息。

    join()当然仍然存在严重的阻塞(停顿)问题。如果可以使用CountedCompleter类,情况会更好。

    并行是指初始线程数。当线程阻塞到最大数量时,该框架会超过此数目(java.util.concurrent.ForkJoinPool.common.maximumSpares(除非向后移植,否则Java8中可能不可用))。该框架根据内部规则添加/删除线程(由于它与发行版有关,因此您需要自己查看代码。)另请参见Interface ForkJoinPool.ManagedBlocker及其支持代码。

    10-08 00:11