建议一次提交多个相关任务的线程池的大小

时间:2019-06-03 18:26:12

标签: java multithreading threadpool

我正在尝试制作一个程序,以并行执行可变数量的可能(但不是肯定)的计算繁重的任务。这些(可运行类型的)任务将同时提交,并且一旦所有这些任务完成(即,该池只需要接受初始任务,仅此而已),线程池就应该关闭。 >

在此站点上找到的大多数答案中,问题都与基于服务器的任务(我在合适的桌面上运行程序)或在不定期的时间间隔内接受任务的池有关。在不是特定用途的问题中,答案通常是“取决于情况”。

我对线程的使用经验基本上为零,所以我真的不知道最佳的“线程数与任务强度”比率是多少。

对于上下文,我正在研究的程序处理矩阵的集合(以3D数组表示),其中每个矩阵最多可以包含1000x1000个元素。其中一项任务可能是执行卷积运算,而每一项任务都是对集合中的矩阵之一进行运算。

是否有针对此类特定问题的建议?

2 个答案:

答案 0 :(得分:2)

在询问服务器问题时,您会听到同样的声音:不要做出假设,做出实验。

尝试确定(最坏的情况:猜测)用户在其上运行软件的典型硬件设置。然后确保您可以进行很好的自动化性能测试。然后看看会发生什么。

但事实是:那没有太大帮助。您会看到,在运行自己的服务器时,(希望)可以控制这些计算机忙于处理的工作负载。对于桌面设置,远程用户可以在其框上运行您的代码...您可以归零洞悉在那里还运行了什么。您可能会发现16个线程适合50%的用户。但是其余的也许在他们的机器上做了很多的事情,而16对他们来说已经太多了。

这才是真正的症结所在。无论您为特定的硬件配置找到了什么“好选择”,都无法控制 other 工作负载。

从这个角度来看,我会很保守。对于CPU密集型工作负载,“太多”的线程还是无济于事,因此,请以CPU的数量或更好的内核数量为起点。

除此之外,在这里可能真正有用的是:在您的应用程序中添加某种“数据收集”。含义:让它定期回电,告诉您类似的事情:“这是我正在运行的硬件,我正在使用X线程,而系统上的 other 工作负载为Y”。这可能会帮助您获得一些启发式方法,以 adapt 适应最重要的用户设置。但是要对要收集的数据保持谨慎。先定义要回答的问题,然后提取回答这些问题所需的数据。

答案 1 :(得分:0)

如果您的工作量是计算密集型的(受CPU限制),则可能需要研究实现ForkJoinPoolworker stealing

  

ForkJoinPool与其他类型的ExecutorService的不同之处在于,它采用了工作窃取:池中的所有线程都试图查找并执行提交给池和/或由其他活动任务创建的任务(最终,如果不存在)。当大多数任务产生其他子任务时(大多数ForkJoinTasks也是如此),以及从外部客户端向池中提交许多小任务时,这可以实现高效处理。