使用scalaz的承诺时调用函数

时间:2012-01-11 09:00:35

标签: 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

但如果我将睡眠者的呼叫替换为内联睡眠,它看起来很好 -

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

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

1 个答案:

答案 0 :(得分:8)

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

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

  

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

Scala 2.9开始,有一个新的App特征可以解决大部分问题,因此您需要做的就是编写object Main2 extends App并且它应该可以正常工作。

相关问题