繁体   English   中英

如何设置Scala 2.10并行集合的默认线程数?

[英]How do I set the default number of threads for Scala 2.10 parallel collections?

在2.10之前的Scala中,我可以在defaultForkJoinPool中设置并行性(如本答案中的scala并行集合的并行度 )。 在Scala 2.10中,该API不再存在。 有充分的文献记载,我们可以通过将单个集合( http://docs.scala-lang.org/overviews/parallel-collections/configuration.html )分配给它的taskSupport属性来设置并行性。

但是,我在代码库中使用了并行集合,并且不想在每个单个集合实例中添加额外的两行。 有什么方法可以配置全局默认线程池大小,以便someCollection.par.map(f(_))自动使用默认线程数?

我知道这个问题已经有一个多月了,但是我有完全相同的问题。 谷歌搜索没有帮助,我找不到在新API中看起来有些理智的东西。

如此处建议的那样设置-Dscala.concurrent.context.maxThreads = n: 在Scala 2.10中为所有集合设置并行度? 似乎根本没有任何作用,但是我不确定是否正确使用了它(我在没有显式安装“ scala”的环境中以“ java”运行我的应用程序,这可能是原因)。

我不知道为什么scala-people从适当的package对象中删除了这个基本的setter。

但是,通常可以使用反射来解决不完整/怪异的界面:

def setParallelismGlobally(numThreads: Int): Unit = {
  val parPkgObj = scala.collection.parallel.`package`
  val defaultTaskSupportField = parPkgObj.getClass.getDeclaredFields.find{
    _.getName == "defaultTaskSupport"
  }.get

  defaultTaskSupportField.setAccessible(true)
  defaultTaskSupportField.set(
    parPkgObj, 
    new scala.collection.parallel.ForkJoinTaskSupport(
      new scala.concurrent.forkjoin.ForkJoinPool(numThreads)
    ) 
  )
}

对于那些不熟悉Scala较晦涩的功能的用户,这里有一个简短的解释:

scala.collection.parallel.`package`

使用defaultTaskSupport变量访问包对象(看起来有点像Java的静态变量,但实际上它是包对象的成员变量)。 标识符要求反引号,因为package是保留关键字。 然后,我们得到了我们想要的私有最终字段(getField(“ defaultTaskSupport”)由于某种原因而无法使用?...),告诉它可以访问以便能够对其进行修改,然后将其值替换为我们自己的ForkJoinTaskSupport。

我还不了解创建并行集合的确切机制,但是Combiner特性的源代码表明defaultTaskSupport的值应以某种方式渗透到并行集合中。

请注意,该问题在质量上与一个更老的问题相同:“我的代码库中遍布Math.random(),如何将种子设置为固定数字以进行调试?” (请参见例如: 在Math.random()上设置种子 )。 在这两种情况下,我们都有某种全局的“静态”变量,我们要在100万个不同的地方隐式使用它,我们想对其进行更改,但是该变量没有设置方法=>我们使用反射。

丑陋的地狱,但似乎工作正常。 如果需要限制线程总数,请不要忘记垃圾收集器在单独的线程上运行。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM