我有一个future(doFour
)被执行并将结果传递到平面图。在平面图中,我执行了另外两个future(doOne和doTwo)函数,希望它们可以并行运行,但我看到它们是按顺序运行(2.13)。 Scastie
为什么doOne
和doTwo
不并行执行?
如何让它们并行运行?
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration.Duration
import scala.concurrent.{Await, Future}
object Test {
def doOne(): Future[Unit] = Future {
println("startFirst"); Thread.sleep(3000); println("stopFirst")
}
def doTwo(): Future[Unit] = Future {
println("startSecond"); Thread.sleep(1000); println("stopSecond")
}
def doFour(): Future[Unit] = Future {
println("do 4"); Thread.sleep(1000); println("done 4")
}
def main(args: Array[String]) {
val resOut = doFour().flatMap { a =>
val futureOperations = Seq(doOne(), doTwo())
val res = Future.sequence(futureOperations)
res
}
val stream = Await.result(resOut, Duration.Inf)
}
}
A Future
一经创建就可以执行。因此,此行创建了两个可以潜在执行的Futures
:
val futureOperations = Seq(doOne(), doTwo())
对Future.sequence
的调用将创建一个新的Future
,对于每个期货依次完成,[
val res = Future.sequence(futureOperations)
如果要,则需要使用Future
依次开始
map/flatMap
:val res = doOne().map( _ => doTwo())
使用此代码,doTwo
将在doOne
完成之前才被调用(如果doOne
失败则完全不会被调用]在您的示例中似乎没有发生这种情况的原因是,您正在
Future
中调用阻止操作,该操作正在阻止线程,否则该线程将用于执行其他Future
。因此,尽管有两个Future
可用于执行,但实际上一次只执行一个。如果将代码标记为
blocking
,它将正常工作:
import scala.concurrent.blocking def doOne(): Future[Unit] = Future { blocking{println("startFirst"); Thread.sleep(3000); println("stop First")} } def doTwo(): Future[Unit] = Future { blocking{println("startSecond"); Thread.sleep(1000); println("stop Second")} }
请参阅注释部分,以了解为什么默认行为在不同版本上会有所不同,以及为什么您永远不要对独立Future
的相对执行顺序进行假设。