2

本质上,我正在编写一种算法,该算法涉及将一个大数组中的所有数字相加,每个数字都带有一个参数。我有一堆参数要运行。对我来说,所有数字的总和可能是利用 Java 中的 fork/join 的一个很好的候选者,并且可以使用固定的执行器服务池有效地运行具有不同参数的算法。

但是,有人知道如何将这两者结合起来吗?或者考虑到它们都是线程池并且我们不应该同时拥有两个池,是否可以将它们组合起来?

任何建议将不胜感激。

4

2 回答 2

0

您可以拥有一个池,并将所有任务提交到该池。

主要问题是池应该有多少线程(并行度)。您可以从默认值(N=处理器数量)开始,并以不同的并行度测试吞吐量。我的猜测是峰值吞吐量介于 N 和 2N 之间。

在 Java 8 中,甚至还有一个公共池

静态 commonPool() 适用于大多数应用程序。

FJP 的好处是性能接近最佳且对调优不敏感(只要配置在合理范围内,例如,不是 10*N 线程)

于 2013-03-12T01:37:17.677 回答
0

正如zhong.j.yu 所说,池的数量并不像这些池中同时活动的线程数加起来那么重要。

ForkJoinPool 最适合用于细分/组合方案的任务,正如名称所暗示的那样RecursiveTask。它们可能不是汇总数组值的最佳选择,这听起来像是一种缓存/内存限制的任务。

您应该进行一些分析或至少试验线程数,因为缓存抖动会在某些时候限制性能。

ForkJoinPool 是高度优化的(检查类注释),比 ThreadPoolExecutor 优化得多,但对于内存有限的作业,您不会注意到差异。

根据我的经验,提交到任一池的每个任务都应至少花费 100µs 才能达到最佳平衡。许多小型作业可能会提供最佳的线程利用率,但处理作业队列中的所有 Runnable 会产生开销。

于 2013-03-12T22:28:57.273 回答