2010-02-21 9 views
6

Este programa, después de ejecutar main(), no sale.¿Cómo puedo agregar actores Scala a un programa existente sin interferir con el comportamiento de terminación normal?

object Main 
{ 
    def main(args: Array[String]) { 
     ... // existing code 
     f() 
     ... // existing code 
    } 
    def f() { 
     import scala.actors.Actor._ 
     val a = actor { 
      loop { 
       react { 
       case msg: String => System.out.println(msg) 
       } 
      } 
     } 
     a ! "hello world" 
    } 
} 

Debido a este inesperado efecto secundario, el uso de actores puede verse como algo intrusivo.

Suponiendo que los actores deben continuar funcionando hasta la terminación del programa, ¿cómo harías para preservar el comportamiento original en todos los casos de rescisión?

Respuesta

7

En 2.8 hay una clase DaemonActor que permite esto. En 2.7.x yo podría hackear un programador personalizado que no evite el apagado incluso si todavía hay actores en vivo, o si desea una manera fácil, puede llamar a System.exit() al final de la página principal.

Si piensas en un actor como una especie de hilo liviano, la mayoría de las veces quieres un actor en vivo para evitar la finalización del programa. De lo contrario, si tienes un programa que hace todo su trabajo en actores, necesitarías tener algo en el hilo principal para mantenerlo vivo hasta que todos los actores terminen.

+0

Gracias. Voy a probar 2.8 beta –

4

Después de completar el hilo principal en el ejemplo anterior, el programa todavía tenía un hilo no-demonio ejecutando el actor. Por lo general, es una mala idea terminar brutalmente los hilos en ejecución usando Thread.destroy() o System.exit(), ya que los resultados pueden ser muy malos para su programa, incluidos, entre otros, la corrupción de datos y los interbloqueos. Es por eso que los métodos Thread.destroy() y similares se desaprobaron en Java para el primer lugar. La forma correcta sería implementar explícitamente la lógica de terminación en sus hilos. En el caso de los actores de Scala, esto se reduce a enviar un mensaje de Stop a todos los actores en ejecución y hacer que se detengan cuando lo obtengan. Con este enfoque su eample se vería así:

object Main 
{ 
    case object Stop 
    def main(args: Array[String]) { 
     ... // existing code 
     val a = f() 
     a ! "hello world" 
     ... // existing code 
     a ! Stop 
    } 
    def f() = { 
     import scala.actors.Actor._ 
     actor { 
      loop { 
       react { 
        case msg: String => System.out.println(msg) 
        case Stop => exit() 
       } 
      } 
     } 
    } 
} 
+0

Por desgracia, la gestión de la vida del actor de forma manual es lo que quería evitar ... Es intrusivo, ya que tengo que cambiar main(). –

Cuestiones relacionadas