2010-02-21 11 views
6

Dieses Programm wird nach dem Ausführen von main() nicht beendet.Wie kann ich Scala-Actors zu einem bestehenden Programm hinzufügen, ohne das normale Abbruchverhalten zu beeinträchtigen?

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" 
    } 
} 

Aufgrund dieses unerwarteten Nebeneffekts kann die Verwendung von Schauspielern als aufdringlich angesehen werden.

Angenommen, die Akteure müssen bis zum Programmende weiterlaufen, wie würden Sie das ursprüngliche Verhalten in allen Fällen der Beendigung beibehalten?

Antwort

7

In 2.8 gibt es eine DaemonActor-Klasse, die dies ermöglicht. In 2.7.x konnte ich einen benutzerdefinierten Scheduler hacken, der das Herunterfahren nicht verhindert, selbst wenn es noch aktive Akteure gibt, oder wenn Sie eine einfache Möglichkeit wünschen, System.exit() am Ende von main aufzurufen.

Wenn Sie einen Akteur als eine Art leichten Faden betrachten, möchten Sie oft, dass ein Live-Akteur einen Programmabbruch verhindert. Ansonsten, wenn Sie ein Programm haben, das all seine Arbeit in Schauspielern ausführt, müssen Sie etwas im Hauptthread haben, um es am Leben zu erhalten, bis alle Schauspieler fertig sind.

+0

Danke. Ich werde versuchen, 2.8 beta –

4

Nachdem der Hauptthread im obigen Beispiel beendet wurde, hatte das Programm immer noch einen Nicht-Daemon-Thread, der den Actor ausführt. Es ist normalerweise eine schlechte Idee, laufende Threads mithilfe von Thread.destroy() oder System.exit() brutal zu beenden, da die Ergebnisse für Ihr Programm sehr schädlich sein können, einschließlich, aber nicht beschränkt auf Datenkorruption und Deadlocks. Aus diesem Grund wurden Thread.destroy() und ähnliche Methoden in Java für den ersten Platz veraltet. Der richtige Weg wäre, explizit Terminierungslogik in Ihren Threads zu implementieren. Im Falle von Scala-Akteuren, die darauf hinauslaufen, eine Stop-Nachricht an alle laufenden Akteure zu senden und sie zu beenden, wenn sie es bekommen. Mit diesem Ansatz würde Ihr Beispiel wie folgt aussehen:

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

Ach, Managing Actor Lebensdauer manuell ist, was ich vermeiden wollte ... Es ist aufdringlich, wie ich main() ändern muss. –

Verwandte Themen