Scala的Actor相似於Java中的多線程編程。可是不一樣的是,Scala的Actor提供的模型與多線程有所不一樣。Scala的Actor儘量地避免鎖和共享狀態,從而避免多線程併發時出現資源爭用的狀況,進而提高多線程編程的性能。此外,Scala Actor的這種模型還能夠避免死鎖等一系列傳統多線程編程的問題。 Spark中使用的分佈式多線程框架,是Akka。Akka也實現了相似Scala Actor的模型,其核心概念一樣也是Actor編程
Actor的建立、啓動和消息收發多線程
1 // Scala提供了Actor trait來讓咱們更方便地進行actor多線程編程,就Actor trait就相似於Java中的Thread和Runnable同樣,是基礎的多線程基類和接口。咱們只要重寫Actor trait的act方法,便可實現本身的線程執行體,與Java中重寫run方法相似。 2 // 此外,使用start()方法啓動actor;使用!符號,向actor發送消息;actor內部使用receive和模式匹配接收消息 3 4 // 案例:Actor Hello World 5 import scala.actors.Actor 6 7 class HelloActor extends Actor { 8 def act() { 9 while (true) { 10 receive { 11 case name: String => println("Hello, " + name) 12 } 13 } 14 } 15 } 16 17 val helloActor = new HelloActor 18 helloActor.start() 19 helloActor ! "leo"
收發case class類型的消息併發
1 // Scala的Actor模型與Java的多線程模型之間,很大的一個區別就是,Scala Actor自然支持線程之間的精準通訊;即一個actor能夠給其餘actor直接發送消息。這個功能是很是強大和方便的。 2 // 要給一個actor發送消息,須要使用「actor ! 消息」的語法。在scala中,一般建議使用樣例類,即case class來做爲消息進行發送。而後在actor接收消息以後,可使用scala強大的模式匹配功能來進行不一樣消息的處理。 3 // 案例:用戶註冊登陸後臺接口 4 case class Login(username: String, password: String) 5 case class Register(username: String, password: String) 6 class UserManageActor extends Actor { 7 def act() { 8 while (true) { 9 receive { 10 case Login(username, password) => println("login, username is " + username + ", password is " + password) 11 case Register(username, password) => println("register, username is " + username + ", password is " + password) 12 } 13 } 14 } 15 } 16 val userManageActor = new UserManageActor 17 userManageActor.start() 18 userManageActor ! Register("leo", "1234"); userManageActor ! Login("leo", "1234")
Actor之間互相收發消息框架
1 // 若是兩個Actor之間要互相收發消息,那麼scala的建議是,一個actor向另一個actor發送消息時,同時帶上本身的引用;其餘actor收到本身的消息時,直接經過發送消息的actor的引用,便可以給它回覆消息。 2 // 案例:打電話 3 case class Message(content: String, sender: Actor) 4 class LeoTelephoneActor extends Actor { 5 def act() { 6 while (true) { 7 receive { 8 case Message(content, sender) => { println("leo telephone: " + content); sender ! "I'm leo, please call me after 10 minutes." } 9 } 10 } 11 } 12 } 13 class JackTelephoneActor(val leoTelephoneActor: Actor) extends Actor { 14 def act() { 15 leoTelephoneActor ! Message("Hello, Leo, I'm Jack.", this) 16 receive { 17 case response: String => println("jack telephone: " + response) 18 } 19 } 20 }
同步消息和Future異步
1 // 默認狀況下,消息都是異步的;可是若是但願發送的消息是同步的,即對方接受後,必定要給本身返回結果,那麼可使用!?的方式發送消息。即val reply = actor !? message。 2 3 // 若是要異步發送一個消息,可是在後續要得到消息的返回值,那麼可使用Future。即!!語法。val future = actor !! message。val reply = future()。