ActorsThe actor modelBasic conceptsA really short exampleA longer exampleActor is a traitTwo ways to create an ActorHow to start an ActorHow to tell an Actor to do one thingHow to tell an Actor to do several thingsSending and receiving messagesWaiting for a message that never comesGetting a result back from an ActorActors and shared stateCounting true/false values: OutlineThe main methodThe Counter classThe same program, all on one slideTypical resultsCounting 3sMain methodcount3sSequentiallycount3sConcurrentlyThe segment methodSlide 25Analysis of resultsMinimizing Thread creationUsing conventional shared stateDoing it rightThe EndJan 14, 2019ActorsConcurrency made easy(-er)2The actor modelMost of the problems with concurrency--from deadlocks to data corruption--result from having shared stateSolution: Don’t share state!An alternative to shared state is the actor model, in which independent processes send to and receive messages from one anotherThe actor model was developed in the Erlang language, and is being incorporated into many new languagesQuoting Alex Miller, http://www.javaworld.com/javaworld/jw-02-2009/jw-02-actor-concurrency1.html?page=2:The actor model consists of a few key principles:No shared stateLightweight processesAsynchronous message-passingMailboxes to buffer incoming messagesMailbox processing with pattern matching3Basic conceptsAn actor is an independent flow of controlYou can think of an actor as a Thread with extra featuresAn actor does not share its data with any other processThis means you can write it as a simple sequential process, and avoid a huge number of problems that result from shared stateHowever: It is possible to share state; it’s just a very bad ideaAny process can send a message to an actor with the syntax actor ! messageAn actor has a “mailbox” in which it receives messagesAn actor will process its messages one at a time, in the order that it receives them, and use pattern matching to decide what to do with each messageExcept: Messages which don’t match any pattern are ignored, but remain in the mailbox (this is bad)An actor doesn’t do anything unless/until it receives a message4A really short examplescala> import scala.actors.Actor._import scala.actors.Actor._scala> val me = selfme: scala.actors.Actor = scala.actors.ActorProxy@6013a567self is a method that returns the currently executing actorSince we didn’t call self from an actor, but just from a plain old Thread, it actually returns a proxy for the Threadscala> me ! 42Sending myself the message 42Doesn’t wait for an answer--just continues with the next codeNothing is printed because the value of this expression is Unitscala> receive { case x => println(x) }42The pattern x is a simple variable, so it will match anythingThe message is received and printed5A longer exampleimport scala.actors.Actorimport scala.actors.Actor._object TGIF { val worker = actor { loop { receive { case "Friday" => println("Thank God it's Friday!") case "Saturday" => exit case x => println("It's " + x + " and I'm working hard.") } } } def main(args: Array[String]) { val days = "Monday Tuesday Wednesday Thursday Friday Saturday Sunday" for (day <- days.split(" ")) worker ! day }}It's Monday and I'm working hard.It's Tuesday and I'm working hard.It's Wednesday and I'm working hard.It's Thursday and I'm working hard.Thank God it's Friday!Process .../bin/scala exited with code 06Actor is a traitA Scala trait is used like a Java interfaceYou can extend only one class, but you can with any number of traitsExample: class Employee extends Person with BenefitsExample: class Secretary extends Employee with ActorHowever, if you don’t explicitly extend a class, use extends for the first traitExample: class Person extends Life with Liberty with HappinessI don’t know the reasons for this rather strange exceptionA trait, like an interface, can require you to supply certain methodsIn an Actor, you must provide def act = ...7Two ways to create an Actor1. You can mix in the Actor traitExample: class Secretary extends Employee with ActorExample: class Worker extends ActorYour class extends a class, but withs a Trait1. Exception: If you don’t explicitly extend some class, you must use extends for the first trait1. I have no clue what the reason is for this ruleA Trait, like a Java interface, can require you to supply certain methodsThe Actor trait requires you to define an act method (with no parameters)nYou can use the actor factory methodExample: val myWorker = actor { ...code for the actor to execute... }The code is what you would otherwise put in the act method8How to start an ActorWhen you define a object that mixes in the Actor trait, you need to start it running explicitlyExample:class Worker extends Actor { ... }val worker1 = new Workerworker1 startWhen you use the actor factory method, the actor is started automaticallyAn actor doesn’t have to wait for messages before it starts doing work--you can write actors that already know what to do9How to tell an Actor to do one thingHere’s an actor that does one thing, once:class Worker extends Actor { def act = receive { case true => println("I am with you 1000%.") case false => println("Absolutely not!") case _ => println("Well, it's complicated....") }}val worker = new Worker().startworker ! 43Here’s another:val worker = actor { receive { case true => println("I am with you 1000%.") case false => println("Absolutely not!") case _ => println("Well, it's complicated....") }}worker ! 4310How to tell an Actor to do several thingsWhen an actor finishes its task, it quitsTo keep an actor going, put receive in a loopExample:class Counter(id: Int) extends Actor { var yes, no = 0 def act = loop { react { case true => yes += 1 case false => no += 1 case "printResults" => printf("Counter #%d got %d yes, %d no.\n", id, yes, no) case x => println("Counter " + id + " didn't understand " + x) } }}This is a special kind of loop defined in the Actor objectThere is also a loopWhile(condition) {...} methodOther kinds of loops will work with receive (but not react)11Sending and receiving messagesTo send a message, use actor ! messageThe thread sending the message keeps going--it doesn’t wait
View Full Document