首页 > 解决方案 > ForkJoinPool 的运行状况和调整

问题描述

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

  1. 在 ForkJoinPools 的上下文中,并行性意味着什么,为不同的线程池(阻塞/非阻塞)选择哪些值的准则/最佳实践是什么?

  2. 如何监控和调整我的 ForkJoinPool?我们正在使用 ForkJoinPool.toString() ,它提供了一些计数器,但我在 javadoc 中找不到有关如何使用此统计信息进行调整的足够信息。getStealCount()被描述为“....应该足够高以保持线程忙碌,但足够低以避免开销和跨线程争用”,这并没有真正的帮助。

toString() 示例

[Running, parallelism = 48, size = 47, active = 0, running = 0, steals
= 33195, tasks = 0, submissions = 0]

标签: javajava-8fork-joinforkjoinpool

解决方案


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

早在 2011 年,我就写了一篇关于 F/J 代码的评论。我多次升级了评论,不再浪费我的时间。

窃取计数完全没有价值。

每个线程都没有统计信息,因此,活动、运行、任务等让您不了解框架内部发生的情况。这些“监视器”中的大多数都是在最初的 Java7 首次亮相多年后才添加的。例如,对于每个线程,了解处理的总 compute() 方法、总等待时间等将使您了解每个线程的执行情况。但是,由于框架添加/删除线程(参见下面的并行性),这永远不会发生。对这些监视器中的任何一个进行总计数并不能告诉您任何有用的信息。

join() 当然,在阻塞(停滞)方面仍然存在严重问题。如果你可以使用 CountedCompleter 类,你会更好。

并行度是指初始线程的数量。当线程阻塞达到最大值时,框架会超过此数量(java.util.concurrent.ForkJoinPool.common.maximumSpares(这在 Java8 中可能不可用,除非它被反向移植))。框架根据内部规则添加/删除线程(您需要自己查看代码,因为它依赖于发布。)另请参见接口 ForkJoinPool.ManagedBlocker 和支持它的代码。


推荐阅读