Programmier Sprachen

Programmier Sprachen wie Java, Scala, C++, C und viele mehr, sind nicht immer leicht. Daher möchte ich hier mein Wissen mit jedem Teilen der Interesse daran hat. Über Anregungen, Hilfe und Verbesserungen sowie positiver und auch negativer Kritik freue ich mich immer.



E-Mail Drucken PDF

Actoren in Scala

So hier nun mal zum Thema Actoren in Scala.

Ich habe mich ja damit nun auch auseinander gesetzt. Und ich muss sagen, hübsche Sache Cool Ein Problem hatte ich jedoch, wie geht das ganze los. Hier erstmal ein kleines Code Beispiel und unten erkläre ich. Bitte nicht über den Sinn oder Unsinn dieser Zeilen nach denken, es geht nur darum das zu verstehen.

package wp11

import scala.actors._
import scala.actors.Actor._

object Try {

  /**
   * @param args the command line arguments
   */
  def main(args: Array[String]): Unit = {
    Dog.start
    Cat.start
    for( i <- 1 to 10) {
      Dog ! "wuff"
      Dog ! 12
      println("schlafe")
      Thread.sleep(300)
    }
    Dog ! EXIT
  }

}

case object EXIT

case object Dog extends Actor {
  def act {
    loop {
      react {
        case "wuff" => println("Wau Wau")
          Cat ! "mathe"
        case EXIT => exit
        case _ => println("Anything")
      }
    }
  }

}

case object Cat extends Actor {

  def act {
    link(Dog) // Sollte Dog ein Exit bekommen, ist dieser damit verbunden!!!
    trapExit = true // Hiermit bekommt auch dieser "Dämon" ein Exit geschickt!!!!
    loop {
      react {
        case "miau" =>
          println("--------------> ich schlafe in Katze!")
          Thread.sleep(300)
          println("--------------> Mauz Mauz")
        case "mathe" => println ("--------------> " + math.random * 1000 )
          println("--------------> Schlafe in Katze")
          Thread.sleep(200)
        case Exit(a,b) => exit
      }
    }
  }
}



    Dog.start
    Cat.start

Hier mit werden beide Actoren gestartet. Es ist wie in Java nur mit .start
Damit aber das Verständnis da ist, die beiden machen nichts weiter als die run Methode abzuarbeiten. Ist da ein

loop
oder
while(true)
, dann ist dies eine Endlosschleife. Sprich so lange wie die nicht  beendet werden, laufen sie rum.

    for( i <- 1 to 10) {
      Dog ! "wuff"
      Dog ! 12
      println("schlafe")
      Thread.sleep(300)
    }

Hier wird einfach 10 mal an den Hund die Nachricht Asyncron "wuff" geschickt. Danach wird wieder Asyncron die "12" geschickt. Danach geht dieser Thread, welcher unabhängig von dem Dog und Cat läuft für 300 ms schlafen. Achtung, es sind dann 3 Threads am werkeln!!! Einmal der erste für die main, dann der zweite für Dog und noch ein Dritter für Cat!

    Dog ! EXIT

Hiermit senden wir die Case Class EXIT an unseren Hund, damit er sich terminiert!

case object Dog extends Actor {
  def act {
    loop {
      react {
        case "wuff" => println("Wau Wau")
          Cat ! "mathe"
        case EXIT => exit
        case _ => println("Anything")
      }
    }
  }

}

Nun wird es spannend Wink. Wir machen Pattern Matching :) Juhuuu
loop ist eine Endlosschleife und läuft endlos. Das react sorgt dafür, dass wir auf unsere Nachrichten reagieren können. Es gibt auch noch receive, welches jedoch ein wenig anders ist, dazu aber später mehr.
Wir testen ob die Nachricht einem String mit "wuff" entspricht. Wenn ja, dann schicken wir der Cat eine Nachricht. Bei Exit, genau beenden wir diesen Thread. Bei allen anderen Nachrichten die nicht zugeordnet werden können,  sagen wir einfach Anything. Achtung hier geben wir tatsächlich nichts zurück, da ist ein Asyncroner Versand absolut ausreichend.

case object Cat extends Actor {

  def act {
    link(Dog) // Sollte Dog ein Exit bekommen, ist dieser damit verbunden!!!
    trapExit = true // Hiermit bekommt auch dieser "Dämon" ein Exit geschickt!!!!
    loop {
      react {
        case "miau" =>
          println("--------------> ich schlafe in Katze!")
          Thread.sleep(300)
          println("--------------> Mauz Mauz")
        case "mathe" => println ("--------------> " + math.random * 1000 )
          println("--------------> Schlafe in Katze")
          Thread.sleep(200)
        case Exit(a,b) => exit
      }
    }
  }
}

link(): verbindet diesen Actor mit einem anderne Actor.
trapExit = true sorgt dafür, dass ich auch die Nachricht Exit(x,y) bekomme. Exit(x,y) ist das standard Object welches man dann bekommt. Ohne trapExit = true, geht es nicht!!
Das Pattern Matching ist ja nun bekannt und langweilig.
Aber der letzte Case Fall ist interessant.
Damit bekomme ich mitgeteilt das mein gelinkter Actor sich verabschiedet hat. Damit weiß ich also, dass ich mich entweder auch beende oder was anderes machen muss.

So, dass sollte es gewesen sein.

Aktualisiert ( Dienstag, den 22. Juni 2010 um 19:02 Uhr )