Scala Actor的併發程式設計
阿新 • • 發佈:2019-01-09
1.什麼是Scala Actor
概念 Scala中的Actor能夠實現並行程式設計的強大功能,它是基於事件模型的併發機制,Scala是運用訊息(massage)的傳送,接收來實現多執行緒的,使用Scala能夠更能夠地實現多執行緒應用的開發。
2.1傳統java併發程式設計與Scala Actor程式設計的區別
'
2.2 對於Java,它的多執行緒實現需要對共享資源(變數,物件等)使用synchronized關鍵字進行程式碼塊同步,物件鎖互斥等等,而且,常常一大塊的try。。。catch語句塊中加上wait方法,notify方法,notifyAll方法是讓人很頭疼的,原因在於Java中對數使用的是可變狀態的物件資源,對這些資源進行共享來實現多執行緒編碼的話,控制好資源競爭與防止物件狀態被意外修改是非常重要的,而物件的不變性也是較難以保證的,而在Scala中,我們可以賦值不可變狀態的資源(即物件,Scala中一切都是物件,連函式,方法也是)的一個副本,再基於Actor的訊息傳送,接收機制並行程式設計
2.3.Actor方法執行順序
1.首先呼叫start()方法啟動Actor
2.呼叫start()方法後其act()方法會被執行
3.向Actor傳送訊息
2.4.傳送訊息的方式
3. Actor實戰 例項一
package practice import scala.actors.Actor object MyActor1 extends Actor{ override def act(): Unit = { for (i<- 1 to 10){ println("actor" +i) Thread.sleep(2000) } } } object MyActor2 extends Actor{ override def act(): Unit = { for ( i <- 1 to 10 ){ println("actor-2" +i) Thread.sleep(2000) } } } object ActotTest extends App{ MyActor1.start() MyActor2.start()
說明:上面分別呼叫兩個單例物件的start()方法,他們的act()方法會被執行,相同與在java中開啟兩個執行緒,執行緒的run() 方法會被執行
注意:這兩個Actor是並行的執行的,act() 方法中的for迴圈執行完成後actor程式就退出了
-------------------------------------------------------------------------------------------------------------------
第二個例項(可以不斷地接收訊息)
package practice //自己給自己傳送訊息 import scala.actors.Actor class MyActor extends Actor{ override def act(): Unit = { while (true){ receive{ case "start" =>{ println("starting.....") Thread.sleep(5000) println("started") } case "stop" =>{ println("stoping ....") Thread.sleep(5000) println("stopped") } } } } } object MyActor { def main(args: Array[String]): Unit = { val actor = new MyActor actor.start() actor ! "start" actor ! "stop" println("訊息傳送完成") } } import scala.actors.Actor class MyActor extends Actor{ override def act(): Unit = { while (true){ receive{ case "start" =>{ println("starting.....") Thread.sleep(5000) println("started") } case "stop" =>{ println("stoping ....") Thread.sleep(5000) println("stopped") } } } } } object MyActor { def main(args: Array[String]): Unit = { val actor = new MyActor actor.start() actor ! "start" actor ! "stop" println("訊息傳送完成") } }
說明:在act()方法加入了while(true)迴圈,就可以不停的接收訊息
注意:傳送start訊息和stop的訊息是非同步的,但是Actor接收到訊息執行的過程是同步的按順序執行
----------------------------------------------------------------------------------------------------------
3.3 第三個例子(react 方式會複用執行緒,比receive更高效)
package practice
import scala.actors.Actor
class YourActor extends Actor{
override def act(): Unit = {
loop{
react{
case "start" => {
println("starting ...")
Thread.sleep(5000)
println("started")
}
case "stop" => {
println("stopping ...")
Thread.sleep(8000)
println("stopped ...")
}
}
}
}
}
object YourActor {
def main(args: Array[String]) {
val actor = new YourActor
actor.start()
actor ! "start"
actor ! "stop"
println("訊息傳送完成!")
}
}
說明:react 如果要反覆執行訊息出來,react外層要用loop,不能用while
3.4 第四個例子(結合case class 傳送訊息)
package practice
import scala.actors.Actor
case class SyncMsg(id:Int,msg:String)
case class AsyncMsg(id:Int,msg:String)
case class ReplyMsg(id:Int,msg:String)
class AppleActor extends Actor{
override def act(): Unit = {
while (true){
receive{
case "start" => println("starting ....")
case SyncMsg(id,msg) =>{
println(id+",sync"+msg)
Thread.sleep(5000)
sender !ReplyMsg(3,"finished")
}
case AsyncMsg(id,msg) =>{
println(id +",astnc"+msg)
Thread.sleep(5000)
}
}
}
}
}
object AppleActor{
def main(args: Array[String]): Unit = {
val a=new AppleActor
a.start()
//非同步訊息
a ! AsyncMsg(1,"hello actor")
println("非同步訊息傳送完成")
//同步訊息
val reply= a !! SyncMsg(2 ,"hello actor")
println(reply.isSet)
val c=reply.apply()
println(reply.isSet)
println(c)
}
}