Función de llamar cuando use la promesa de Scalaz
Pregunta
Como novato de Scala y Scalaz, cuando se usa Promise, obtuvo un problema. Mi código me gusta este.
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())
}
Esta salida siguiente, que parece extraña. Parece que el método durmiente no se ha llamado, y el hilo bloqueado. -
begin
try to get
Pero si reemplazo el durmiente llamando a un sueño en línea, se ve bien -
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())
}
Salida aquí -
begin
ok
try to get
ok
No entiendo por qué, ¿puedes asesorar por favor?
Solución
No puedo darle una explicación completa, pero el problema parece estar conectado a algunos problemas con el Application
rasgo.
En resumen: el cuerpo del constructor de Application
se ejecuta demasiado temprano y en un contexto de inicialización estática. En ese punto, no maneja muy bien los hilos (si es que lo hacen). los Apidoc actual dice:
El código roscado que hace referencia al objeto bloqueará hasta que se complete la inicialización estática. Sin embargo, debido a que la ejecución completa de una aplicación de extensión de objeto tiene lugar durante la inicialización estática, el código concurrente siempre se bloqueará si debe sincronizar con el objeto de encerrado.
Empezando desde Scala 2.9, ahí está el nuevo App
rasgo que resuelve la mayoría de estos problemas, por lo que todo lo que necesita hacer es escribir object Main2 extends App
Y debería funcionar.