gpt4 book ai didi

scala - 为什么 scala Await.result 在两次通过相同的 future 时在 repl 中超时?

转载 作者:行者123 更新时间:2023-12-04 15:11:28 26 4
gpt4 key购买 nike

我发现这有点令人困惑。我认为 scala 中的 future 是不可变的容器,一旦设置,总是返回相同的值。

所以我有一个 future :

val y = future {Thread.sleep(1000); 1};

现在,当我立即(在 future 解决之前)将其传递给 Await.result阻止两次:
Await.result(for (r1 <- y; r2 <- y) yield (r1, r2), 60 seconds)

我得到一个 TimetoutException .

但是,如果我在 future 解决后这样做,一切正常并返回 (1,1)正如预期的那样。

这种行为的原因是什么?

编辑:
我正在使用隐式 ExecutionContext.Implicits.globalscala.concurrent @ 斯卡拉 2.10.3

编辑2:
如果我创建另一个执行相同操作的 future 实例并对它们执行 Await.result ,则它不会阻塞。

最佳答案

这似乎是在 REPL 中执行它的工件。
您甚至可以使用 2 个单独的 future 实例来重现它,而无需调用 Thread.sleep。 ,
并且仅使用预先实现的 future (这意味着甚至没有涉及任何 future 线程)。
是的,说真的:

import scala.concurrent._
import duration._
import ExecutionContext.Implicits.global
val x = Future.successful(1)
val y = Future.successful(2)
Await.result(x.flatMap{_ => y.map{ _ => 0 } }, Duration(10, SECONDS)) // triggers a timeout

有趣的是,如果您将最后一行更改为以下内容,这不会触发任何超时:
Await.result(x.flatMap{_ => Future.successful(2).map{ _ => 0 } }, Duration(10, SECONDS))

似乎罪魁祸首是你的整个代码片段,当在 REPL 中进行评估时,实际上是包装在一个对象中。
这意味着 xy这里实际上是对象的成员,而不是局部变量
更重要的是,对 Await 的调用现在是这个包装对象的构造函数的一部分。
出于某种我尚未调查的原因,似乎是对 Await 的调用在触发阻塞的构造函数中完成
(您可以通过将此调用包装在一个虚拟类中并实例化它来轻松验证它)。

关于scala - 为什么 scala Await.result 在两次通过相同的 future 时在 repl 中超时?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23108731/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com