繁体   English   中英

在 Future.sequence 的成功上的片状

[英]Flaky onSuccess of Future.sequence

我写了这个方法:

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

object FuturesSequence extends App {
  val f1 = future {
    1
  }

  val f2 = future {
    2
  }

  val lf = List(f1, f2)

  val seq = Future.sequence(lf)

  seq.onSuccess {
    case l => println(l)
  }
}

我期待 Future.sequence 将 List[Future] 收集到 Future[List] 中,然后等待每个期货(在我的情况下为 f1 和 f2)完成,然后在我的情况下对 Future[List] seq 调用 onSuccess。

但是在多次运行此代码后,它只会偶尔打印一次“List(1, 2)”,我无法弄清楚为什么它没有按预期工作。

试试这个,

import scala.concurrent._
import java.util.concurrent.Executors
import scala.util.{ Success, Failure }

object FuturesSequence extends App {
  implicit val exec = ExecutionContext.fromExecutor(Executors.newCachedThreadPool)
  val f1 = future {
    1
  }

  val f2 = future {
    2
  }

  val lf = List(f1, f2)

  val seq = Future.sequence(lf)

  seq.onSuccess {
    case l => println(l)
  }
}

这将始终打印List(1,2) 原因很简单,上面的exec是一个线程(不是守护线程)的 ExecutionContext ,在您的示例中, ExecutionContext 是从ExecutionContext.Implicits.global隐式获取的默认值,其中包含守护线程。

因此,作为守护进程,进程不会等待seq未来完成并终止。 如果seq确实完成了,那么它就会打印出来。 但这并不总是发生

应用程序在未来完成之前退出。

你需要阻塞直到未来完成 这可以通过多种方式实现,包括更改 ExecutionContext、实例化新的 ThreadPool、Thread.sleep 等,或使用scala.concurrent.Await方法

代码最简单的方法是使用Await.ready 这会在指定的时间内阻止future 在下面修改后的代码中,应用程序在退出前等待 5 秒。

还要注意,额外的 import scala.concurrent.duration以便我们可以指定等待的时间。

import scala.concurrent._
import scala.concurrent.duration._
import java.util.concurrent.Executors
import scala.util.{ Success, Failure }

object FuturesSequence extends App {
  val f1 = future {
    1
  }

  val f2 = future {
    2
  }

  val lf = List(f1, f2)

  val seq = Future.sequence(lf)

  seq.onSuccess {
    case l => println(l)
  }

  Await.ready(seq, 5 seconds)
}

通过使用Await.result ,您也可以跳过onSuccess方法,因为它会将结果列表返回给您。

例子:

val seq: List[Int] = Await.result(Future.sequence(lf), 5 seconds)
println(seq)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM