scala - 使用scalaz的promise时调用函数

标签 scala scalaz

作为 scala 和 scalaz 的新手,在使用 promise 的时候,遇到了问题。我的代码是这样的。

import scalaz._
import Scalaz._

object Main2 extends Application {
  def sleeper() = {
    Thread.sleep(2000)
  }
  val message = promise {
    println("begin")
    sleeper
    println("ok")
    "ok"
  }
  Thread.sleep(5000)
  println("try to get")
  println(message())
}

这个输出如下,看起来很奇怪。好像还没有调用 sleeper 方法,线程阻塞了。 -

begin
try to get

但如果我将 sleep 者替换为内联 sleep ,它看起来很好 -

object Main2 extends Application {
  def sleeper() = {
    Thread.sleep(2000)
  }
  val message = promise {
    println("begin")
    Thread.sleep(2000)
    println("ok")
    "ok"
  }
  Thread.sleep(5000)
  println("try to get")
  println(message())
}

在这里输出 -

begin
ok
try to get
ok

不明白为什么,请各位大神指点一下?

最佳答案

我不能给你一个完整的解释,但这个问题似乎与 Application 特性的一些问题有关。

简而言之:Application 的构造函数体运行得太早并且在静态初始化上下文中。那时,它不能很好地处理线程(如果有的话)。 current Apidoc说:

Threaded code that references the object will block until static initialization is complete. However, because the entire execution of an object extending Application takes place during static initialization, concurrent code will always deadlock if it must synchronize with the enclosing object.

Scala 2.9 开始,有一个新的 App trait 可以解决大多数这些问题,所以你需要做的就是编写 object Main2 extends App 并且它应该可以工作。

关于scala - 使用scalaz的promise时调用函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8816588/

相关文章:

scala - 如何在使用 PlaySpecification 编写的 Controller 测试前后执行一组代码?

scala - Scala中的纯FP?

scala - 读者作者状态monad-如何运行此scala代码

测试 Scala 对象

scala - 要么单元操作

Scala 前向引用

sql - 使用 Postgres 枚举进行 JDBC 插入

scala - 如何将 Future 的分离转换为分离的 Future

scala - 状态单子(monad)在恒定空间(堆和堆栈)中的单子(monad)折叠?

scala - Scala 是否可以在脚本中提供类型检查?