嵌套的Future.sequence按顺序执行包含的Futures

问题描述 投票:5回答:1

我有一个future(doFour)被执行并将结果传递到平面图。在平面图中,我执行了另外两个future(doOnedoTwo)函数,希望它们可以并行运行,但我看到它们是按顺序运行(2.13)。 Scastie

为什么doOnedoTwo不并行执行?

如何让它们并行运行?

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)
  }
}
scala concurrency concurrent.futures
1个回答
6
投票

A Future一经创建就可以执行。因此,此行创建了两个可以潜在执行的Futures

val futureOperations = Seq(doOne(), doTwo())

Future.sequence的调用将创建一个新的Future,对于每个期货依次完成,[,但是它们都已经可以在代码中执行了。

val res = Future.sequence(futureOperations)
如果要Future依次

开始

,则需要使用map/flatMapval 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的相对执行顺序进行假设。
© www.soinside.com 2019 - 2024. All rights reserved.