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?

¿Fue útil?

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.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top