作为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
我不明白为什么,请问大师请指教?
答案 0 :(得分:8)
我不能给你一个完整的解释,但问题似乎与Application
特征的某些问题有关。
简而言之:Application
的构造函数体太早运行并处于静态初始化环境中。此时,它不能很好地处理线程(如果有的话)。 current Apidoc说:
引用该对象的线程代码将阻塞,直到静态初始化完成。但是,因为扩展Application的对象的整个执行都是在静态初始化期间进行的,所以如果并发代码必须与封闭对象同步,它们将始终处于死锁状态。
从Scala 2.9开始,有一个新的App
特征可以解决大部分问题,因此您需要做的就是编写object Main2 extends App
并且它应该可以正常工作。