scala學習筆記-Actor(19)

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()。
相關文章
相關標籤/搜索