好程式設計師大資料學習路線分享Actor學習筆記

好程式設計師IT發表於2019-08-19

  好程式設計師大資料學習路線分享 Actor 學習筆記, 在scala中她能實現很強大的功能,他是基於併發機制的一個事件模型

我們現在學的scala2.10.x版本就是之前的Actor

 

同步 :在主程式上排隊執行的任務,只有前一個任務執行完畢後,才能執行下一個任務

非同步 :指不進入主程式,而進入"任務對列"的任務,只有等主程式任務執行完畢,"任務對列"開始請求主程式,請求任務執行,該任務會進入主程式

 

java

共享變數 -- 加鎖

會出現鎖死問題

scala

Actor不共享資料

沒有鎖的概念

Actor通訊之間需要message(通訊)

Aactor執行順序

1.首先呼叫start()方法啟動Actor

2.呼叫start()方法後act()方法會被執行

3.Actor之間進行傳送訊息

Actor傳送訊息的三種方式

! -> 傳送非同步訊息,沒有返回值

!? -> 傳送同步訊息,有返回值,會有執行緒等待

!! -> 傳送非同步訊息,有返回值,返回值型別Future[Any](用來獲取非同步操作結果)

 

Actor並行執行

//注意,這兩個actor會並行執行,當其中一個for迴圈結束後,actor結束

object ActorDemo01 {

  def main(args: Array[String]): Unit = {

    MyActor1.start()

    MyActor2.start()

  }

}

 

object MyActor1 extends Actor{

  override def act(): Unit = {

    for (i <- 1 to 10){

      println(s"actor => $i")

      Thread.sleep(2000)

    }

  }

 

  object MyActor2 extends Actor{

    override def act(): Unit = {

      for (i <- 1 to 5){

        println(s"actor2 => $i")

        Thread.sleep(2000)

      }

    }

  }

}

Actor不斷接受訊息

執行第一種方式,非同步

object ActorDemo02 {

  def main(args: Array[String]): Unit = {

    val actor: MyActor = new MyActor

    actor.start()

 

    //並行執行

    actor ! "start"  // !->非同步

    actor ! "stop"

    println("傳送完成")

 

  }

}

 

class MyActor extends Actor{

  override def act(): Unit = {

    while (true){   //死迴圈

      receive {   //接收

        case "start" => {

          println("starting")

          Thread.sleep(1000)

          println("started")

        }

        case "stop" => {

          println("stopping")

          Thread.sleep(1000)

          println("stopped")

        }

      }

    }

  }

}

第二種方式: 利用react來代替receive,也就是說react執行緒可複用,比receive更高效

object ActorDemo03 {

  def main(args: Array[String]): Unit = {

    val actor: MyActor3 = new MyActor3

    actor.start()

    actor ! "start"

    actor ! "stop"

    println("成功了")

  }

}

 

class MyActor3 extends Actor{

  override def act(): Unit = {

    loop {

      react{

        case "start" =>{

          println("starting")

          Thread.sleep(1000)

          println("sarted")

        }

        case "stop" =>{

          println("stoppting")

          Thread.sleep(1000)

          println("stopped")

        }

      }

    }

  }

}

結合樣例類練習Actor傳送訊息

//建立樣例類

case class AsyncMsg(id: Int, msg: String)

case class SyncMsg(id: Int, msg: String)

case class ReplyMsg(id: Int, msg: String)

 

object ActorDemo01 extends Actor {

  override def act(): Unit = {

    while (true) {

      receive {

        case "start" => println("starting...")

        case AsyncMsg(id, msg) =>

        {

          println(s"id:$id,msg:$msg")

          sender ! ReplyMsg(1,"sucess")  //接收到訊息後返回響應訊息

        }

        case SyncMsg(id,msg) => {

          println(s"id:$id,msg:$msg")

          sender ! ReplyMsg(2,"sucess")

        }

      }

    }

  }

}

 

object ActorTest{

  def main(args: Array[String]): Unit = {

 

    val actor: Actor = ActorDemo01.start()

 

//    //非同步傳送訊息,沒有返回值

//    actor ! AsyncMsg(3,"heihei")

//    println("非同步訊息傳送完成,沒有返回值")

 

//    //同步傳送訊息,有返回值

//    val text: Any = actor !? SyncMsg(4,"OK")

//    println(text)

//    println("同步訊息傳送成功")

 

    //非同步傳送訊息,有返回值,返回型別為Future[Any]

    val reply: Future[Any] = actor !! SyncMsg(5,"OK is 不存在的")

    Thread.sleep(2000)

    if (reply.isSet){

      val applyMsg: Any = reply.apply()

      println(applyMsg)

    }else{

      println("Nothing")

    }

  }

}

Actor並行化的wordcount

class Task extends Actor {

 

  override def act(): Unit = {

    loop {

      react {

        case SubmitTask(fileName) => {

          val contents = Source.fromFile(new File(fileName)).mkString

          val arr = contents.split("\r\n")

          val result = arr.flatMap(_.split(" ")).map((_, 1)).groupBy(_._1).mapValues(_.length)

          //val result = arr.flatMap(_.split(" ")).map((_, 1)).groupBy(_._1).mapValues(_.foldLeft(0)(_ + _._2))

          sender ! ResultTask(result)

        }

        case StopTask => {

          exit()

        }

      }

    }

  }

}

 

object WorkCount {

  def main(args: Array[String]) {

    val files = Array("c://words.txt", "c://words.log")

 

    val replaySet = new mutable.HashSet[Future[Any]]

    val resultList = new mutable.ListBuffer[ResultTask]

 

    for(f <- files) {

      val t = new Task

      val replay = t.start() !! SubmitTask(f)

      replaySet += replay

    }

 

    while(replaySet.size > 0){

      val toCumpute = replaySet.filter(_.isSet)

      for(r <- toCumpute){

        val result = r.apply()

        resultList += result.asInstanceOf[ResultTask]

        replaySet.remove(r)

      }

      Thread.sleep(100)

    }

    val finalResult = resultList.map(_.result).flatten.groupBy(_._1).mapValues(x => x.foldLeft(0)(_ + _._2))

    println(finalResult)

  }

}

 

case class SubmitTask(fileName: String)

case object StopTask

case class ResultTask(result: Map[String, Int])

 


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69913892/viewspace-2654135/,如需轉載,請註明出處,否則將追究法律責任。

相關文章