[英]Nested Future.sequence executes included Futures sequentially
I have a future( doFour
) that is executed and results passed to a flatmap.我有一个执行的未来(
doFour
)并将结果传递给平面图。 Inside the flatmap I execute two more future( doOne and doTwo ) functions expecting them to run on parallel but I see they are running sequentially (2.13).在平面图中,我执行了另外两个未来( doOne和doTwo )函数,期望它们并行运行,但我看到它们是按顺序运行的(2.13)。 Scastie
斯卡斯蒂
Why are doOne
and doTwo
not execute in parallel?为什么
doOne
和doTwo
不能并行执行?
How can I have them to run in parallel?我怎样才能让它们并行运行?
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
becomes eligible for execution as soon as it is created. Future
一经创建就可以执行。 So this line creates two Futures
that can potentially be executed:所以这一行创建了两个可能被执行的
Futures
:
val futureOperations = Seq(doOne(), doTwo())
The call to Future.sequence
will create a new Future
that waits for each of the futures to complete in turn, but they will both already be available for execution by this point in the code.对
Future.sequence
的调用将创建一个新的Future
,它等待每个 Future 依次完成,但它们都已经可以在代码中执行。
val res = Future.sequence(futureOperations)
If you want Future
s to start sequentially you need to use map/flatMap
:如果您希望
Future
s 按顺序启动,您需要使用map/flatMap
:
val res = doOne().map( _ => doTwo())
With this code doTwo
will not be called until doOne
completes (and not at all if doOne
fails)使用此代码,在
doTwo
完成之前不会调用doOne
(如果doOne
失败,则根本不会调用)
The reason that this does not appear to happen in your example is that you are calling a blocking operation in your Future
which is blocking a thread that would otherwise be used to execute other Future
s.在您的示例中似乎没有发生这种情况的原因是您在
Future
中调用了一个阻塞操作,该操作阻塞了一个线程,否则该线程将用于执行其他Future
s。 So although there are two Future
s available for execution, only one is actually being executed at a time.因此,尽管有两个
Future
可用于执行,但实际上一次只执行一个。
If you mark the code as blocking
it works correctly:如果您将代码标记为
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")}
}
See the comments section for details of why the default behaviour is different on different versions, and why you should never make assumptions about the relative execution order of independent Future
s.请参阅评论部分了解为什么不同版本的默认行为不同的详细信息,以及为什么您永远不应该对独立
Future
的相对执行顺序做出假设。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.