为什么我的Scala期货并行执行?

时间:2017-04-08 15:39:03

标签: scala parallel-processing future

我试图并行运行一系列愚蠢的Scala Future。我有以下代码,我希望花费大约10秒钟:

import scala.concurrent.Future
import scala.util.{Success, Failure}
import scala.concurrent.ExecutionContext.Implicits.global

def scalaFoo = Future {
  Thread.sleep(10*1000) // sleep for 10 seconds
  List(1,2,3)
}

def scalaBar = Future {
  Thread.sleep(10*1000)
  List(4,5,6)
}

def scalaBaz = Future {
  Thread.sleep(10*1000)
  List(7,8,9)
}

val flatRes: Future[List[Int]] = for {
  scalaFooRes <- scalaFoo 
  scalaBarRes <- scalaBar
  scalaBazRes <- scalaBaz
} yield (scalaFooRes ++ scalaBarRes ++ scalaBazRes)

flatRes onComplete {
  case Success(li) => println(li.foldLeft(0)(_ + _))
  case Failure(e) => println(e.getMessage)
}

但我发现onComplete需要约30秒,所以我的作业按顺序运行。

如何让它们并行运行?为什么他们现在没有并行运行?

3 个答案:

答案 0 :(得分:4)

您需要在for表达式之前创建它们,否则它们不会并行运行。如果将方法更改为val,则应该可以正常工作。

答案 1 :(得分:2)

您可以首先并行声明变量来运行这些期货:

val foo = scalaFoo
val bar = scalaBar
val baz = scalaBaz

然后为:

for {
  scalaFooRes <- foo 
  scalaBarRes <- bar
  scalaBazRes <- baz
} ...

答案 2 :(得分:1)

您还可以使用Future.sequence:

def scalaFoo = Future {
  Thread.sleep(3*1000) // sleep for 10 seconds
  List(1,2,3)
}

def scalaBar = Future {
  Thread.sleep(3*1000)
  List(4,5,6)
}

def scalaBaz = Future {
  Thread.sleep(3*1000)
  List(7,8,9)
}
Future.sequence(List(scalaFoo, scalaBar, scalaBaz)).onComplete({
  case Success(li) => println(li.flatten.sum)
  case Failure(e) => println(e.getMessage)
})