是否将隐式执行上下文传递给 .par 操作?

Cli*_*ote 1 parallel-processing concurrency scala executioncontext

我有这种情况:

  • 方法a:创建一个隐式ec

  • 方法a:调用Future中的另一个方法,即Future(anotherMethod)anotherMethod,并且其所有后续调用都不再具有方法 a 中的 ec 范围。

示例代码:

class Foo {
  private implicit val ec: ExecutionContextExecutor =
        ExecutionContext.fromExecutor(Executors.newFixedThreadPool(Runtime.getRuntime.availableProcessors()))

  private val anotherClass = new Bar()

  def methodA() = Future(anotherClass.anotherMethod())
}
Run Code Online (Sandbox Code Playgroud)

我猜测,任何对.par,例如someVector.par.map.().seqetc 的调用anotherMethod或其任何后续调用都将使用全局执行上下文,而不是在方法 a 中创建的自定义上下文。我的假设正确吗?

Yuv*_*kov 5

我猜,任何对 .par 的调用,例如 someVector.par.map.().seq 等,来自 anotherMethod 或其任何后续调用,将使用全局执行上下文,而不是在方法 a 中创建的自定义上下文。我的假设正确吗?

让我们将这个答案一分为二。首先,如果您的调用链中有任何其他需要隐式的方法ExecutionContext,它们将获得在您的顶级methodA调用中隐式定义的方法。

否则,Scala 中的并行集合设计没有 an 的概念,ExecutionContext严格来说它是 的一个属性Future。并行集合库有一个 a 的概念,TaskSupport它负责并行集合内部的调度:

*  Parallel collections are modular in the way operations are scheduled. Each
*  parallel collection is parameterized with a task support object which is
*  responsible for scheduling and load-balancing tasks to processors.
Run Code Online (Sandbox Code Playgroud)

因此,这些并行收集不会有什么做的ExecutionContext中声明Foo。但是,您可以通过tasksupportsetter显式设置它们:

val par = List(1,2,3,4).par
par.tasksupport = new ForkJoinTaskSupport(new ForkJoinPool(4))
Run Code Online (Sandbox Code Playgroud)