本质上,我正在编写一种算法,该算法涉及对大数组中的所有数字求和,每个数组都有一个参数。我有一堆参数要运行。对我来说,所有数字的总和可以很好地利用Java中的fork / join,并且可以使用固定的执行服务池有效地运行具有不同参数的算法。
但是,有谁知道如何将这两者结合起来?或者是否可以将它们组合起来,考虑到它们都是线程池,我们不应该同时拥有两个池?
非常感谢任何建议。
答案 0 :(得分:0)
您可以拥有一个池,并将所有任务提交到此池。
主要问题是池应该有多少个线程(并行性)。您可以从默认值(N =处理器数)开始,并使用不同的并行度测试吞吐量。我的猜测是峰值吞吐量介于N和2N之间。
在Java 8中,甚至还有common pool:
静态commonPool()可用,适用于大多数应用程序。
关于FJP的好处是性能接近最优且对调整不敏感(只要配置在合理范围内,比如不是10 * N个线程)
答案 1 :(得分:0)
正如zhong.j.yu所说,池中的数量并不像这些池中的同时活动线程数一样重要。
ForkJoinPool最适合用于细分/组合方案的任务,如名称RecursiveTask
暗示的那样。它们可能不是总结数组值的最佳选择,这听起来像缓存/内存有限的任务。
您应该进行一些分析或至少尝试线程数,因为缓存抖动会在某些时候限制性能。
ForkJoinPool是高度优化的(检查类注释),比ThreadPoolExecutor更多,但对于内存限制的作业,你不会注意到差异。
根据我的经验,提交到任一池的每项任务都应至少花费100μs才能达到最佳平衡。许多小作业可以提供最佳的线程利用率,但是处理作业队列中的所有Runnables需要花费成本。