使用scalaz的承诺时调用函数

Jas*_*son 3 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())
}
Run Code Online (Sandbox Code Playgroud)

此输出如下,看起来很奇怪.似乎没有调用sleeper方法,并且线程被阻塞. -

begin
try to get
Run Code Online (Sandbox Code Playgroud)

但是,如果我更换睡眠者呼叫内联睡眠,它看起来很好 -

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())
}
Run Code Online (Sandbox Code Playgroud)

输出在这里 -

begin
ok
try to get
ok
Run Code Online (Sandbox Code Playgroud)

我不明白为什么,请问大师请指教?

Deb*_*ski 8

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

简而言之:构造函数体Application太早运行并处于静态初始化环境中.此时,它不能很好地处理线程(如果有的话).在当前Apidoc说:

引用该对象的线程代码将阻塞,直到静态初始化完成.但是,因为扩展Application的对象的整个执行发生在静态初始化期间,所以如果并发代码必须与封闭对象同步,则它们将始终死锁.

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