1. 程式人生 > >Akka併發程式設計——第五節:Actor模型(四)

Akka併發程式設計——第五節:Actor模型(四)

本節主要內容:
1. 停止Actor

1. 停止Actor

(1)通過ActorSystem.shutdown方法停止所有 Actor的執行

/*
*停止Actor:ActorSystem.shutdown方法
*/
object Example_10 extends App{
  import akka.actor.Actor
  import akka.actor.ActorSystem
  import akka.actor.Props

  class FirstActor extends Actor with ActorLogging{

    var child:ActorRef = context.actorOf(Props[MyActor], name = "myActor"
) def receive = { //向MyActor傳送訊息 case x => child ! x;log.info("received "+x) } override def postStop(): Unit = { log.info("postStop In FirstActor") } } class MyActor extends Actor with ActorLogging{ def receive = { case "test" => log.info("received test"
); case _ => log.info("received unknown message"); } override def postStop(): Unit = { log.info("postStop In MyActor") } } val system = ActorSystem("MyActorSystem") val systemLog=system.log //建立FirstActor物件 val firstactor = system.actorOf(Props[FirstActor], name = "firstActor"
) systemLog.info("準備向firstactor傳送訊息") //向firstactor傳送訊息 firstactor!"test" firstactor! 123 //關閉ActorSystem,停止所有Acotr執行 system.shutdown() }

程式碼執行結果:

[INFO] [04/02/2016 21:51:34.440] [main] [ActorSystem(MyActorSystem)] 準備向firstactor傳送訊息
[INFO] [04/02/2016 21:51:34.441] [MyActorSystem-akka.actor.default-dispatcher-4] [akka://MyActorSystem/user/firstActor/myActor] received test
[INFO] [04/02/2016 21:51:34.441] [MyActorSystem-akka.actor.default-dispatcher-2] [akka://MyActorSystem/user/firstActor] received test
[INFO] [04/02/2016 21:51:34.441] [MyActorSystem-akka.actor.default-dispatcher-2] [akka://MyActorSystem/user/firstActor] received 123
[INFO] [04/02/2016 21:51:34.441] [MyActorSystem-akka.actor.default-dispatcher-4] [akka://MyActorSystem/user/firstActor/myActor] received unknown message
[INFO] [04/02/2016 21:51:34.446] [MyActorSystem-akka.actor.default-dispatcher-4] [akka://MyActorSystem/user/firstActor/myActor] postStop In MyActor
[INFO] [04/02/2016 21:51:34.447] [MyActorSystem-akka.actor.default-dispatcher-5] [akka://MyActorSystem/user/firstActor] postStop In FirstActor

(2)通過context.stop方法停止Actor的執行

/*
*停止Actor:context.stop方法
*/
object Example_11 extends App{
  import akka.actor.Actor
  import akka.actor.ActorSystem
  import akka.actor.Props

  class FirstActor extends Actor with ActorLogging{

    var child:ActorRef = context.actorOf(Props[MyActor], name = "myActor")
    def receive = {
      case "stop"=>context.stop(child)
      case x =>{
        //向MyActor傳送訊息
        child ! x
        log.info("received "+x)
      }

    }
    override def postStop(): Unit = {
      log.info("postStop In FirstActor")
    }
  }

  class MyActor extends Actor with ActorLogging{
    def receive = {
      case "test" => log.info("received test");
      case _      => log.info("received unknown message");
    }
    override def postStop(): Unit = {
      log.info("postStop In MyActor")
    }
  }
  val system = ActorSystem("MyActorSystem")
  val systemLog=system.log

  //建立FirstActor物件
  val firstactor = system.actorOf(Props[FirstActor], name = "firstActor")

  systemLog.info("準備向firstactor傳送訊息")
  //向firstactor傳送訊息
  firstactor!"test"
  firstactor! 123
  firstactor!"stop"

}

程式碼執行結果:

[INFO] [04/02/2016 22:02:48.760] [main] [ActorSystem(MyActorSystem)] 準備向firstactor傳送訊息
[INFO] [04/02/2016 22:02:48.761] [MyActorSystem-akka.actor.default-dispatcher-5] [akka://MyActorSystem/user/firstActor/myActor] received test
[INFO] [04/02/2016 22:02:48.761] [MyActorSystem-akka.actor.default-dispatcher-2] [akka://MyActorSystem/user/firstActor] received test
[INFO] [04/02/2016 22:02:48.762] [MyActorSystem-akka.actor.default-dispatcher-2] [akka://MyActorSystem/user/firstActor] received 123
[INFO] [04/02/2016 22:02:48.762] [MyActorSystem-akka.actor.default-dispatcher-5] [akka://MyActorSystem/user/firstActor/myActor] received unknown message
[INFO] [04/02/2016 22:02:48.763] [MyActorSystem-akka.actor.default-dispatcher-5] [akka://MyActorSystem/user/firstActor/myActor] postStop In MyActor

程式碼的重點為

class FirstActor extends Actor with ActorLogging{

    var child:ActorRef = context.actorOf(Props[MyActor], name = "myActor")
    def receive = {
      case "stop"=>context.stop(child)
      case x =>{
        //向MyActor傳送訊息
        child ! x
        log.info("received "+x)
      }

    }
    override def postStop(): Unit = {
      log.info("postStop In FirstActor")
    }
  }

中的case “stop”=>context.stop(child),直接通過context.stop方法停止Actor的執行。注意程式中並沒有使用system.shutdown方法,因此整個程式的不會停止,如下圖所示
這裡寫圖片描述

(3)通過akka.actor.PoisonPill訊息停止Actor的執行

/*
*停止Actor:使用akka.actor.PoisonPill
*/
object Example_12 extends App{
  import akka.actor.Actor
  import akka.actor.ActorSystem
  import akka.actor.Props
  import akka.actor.PoisonPill

  class FirstActor extends Actor with ActorLogging{

    var child:ActorRef = context.actorOf(Props[MyActor], name = "myActor")
    def receive = {
      //向child傳送PoisonPill停止其執行
      case "stop"=>child!PoisonPill
      case x =>{
        //向MyActor傳送訊息
        child ! x
        log.info("received "+x)
      }

    }
    override def postStop(): Unit = {
      log.info("postStop In FirstActor")
    }
  }

  class MyActor extends Actor with ActorLogging{
    def receive = {
      case "test" => log.info("received test");
      case _      => log.info("received unknown message");
    }
    override def postStop(): Unit = {
      log.info("postStop In MyActor")
    }
  }
  val system = ActorSystem("MyActorSystem")
  val systemLog=system.log

  //建立FirstActor物件
  val firstactor = system.actorOf(Props[FirstActor], name = "firstActor")

  systemLog.info("準備向firstactor傳送訊息")
  //向firstactor傳送訊息
  firstactor!"test"
  firstactor! 123
  firstactor!"stop"

}

程式碼執行結果:

[INFO] [04/02/2016 22:12:09.947] [main] [ActorSystem(MyActorSystem)] 準備向firstactor傳送訊息
[INFO] [04/02/2016 22:12:09.947] [MyActorSystem-akka.actor.default-dispatcher-2] [akka://MyActorSystem/user/firstActor/myActor] received test
[INFO] [04/02/2016 22:12:09.947] [MyActorSystem-akka.actor.default-dispatcher-4] [akka://MyActorSystem/user/firstActor] received test
[INFO] [04/02/2016 22:12:09.947] [MyActorSystem-akka.actor.default-dispatcher-4] [akka://MyActorSystem/user/firstActor] received 123
[INFO] [04/02/2016 22:12:09.947] [MyActorSystem-akka.actor.default-dispatcher-2] [akka://MyActorSystem/user/firstActor/myActor] received unknown message
[INFO] [04/02/2016 22:12:09.951] [MyActorSystem-akka.actor.default-dispatcher-4] [akka://MyActorSystem/user/firstActor/myActor] postStop In MyActor

程式碼與Exampel_11中的不同之處在於

//向child傳送PoisonPill停止其執行
case "stop"=>child!PoisonPill

它使用不是context.stop方法,而是向MyActor傳送了PoisonPill訊息,其它程式碼不變。

還有一種gracefulStop方法可以停止Actor的執行,這部分內容等了解完Future類的作用原理之後再來討論

Scala學習(公眾微訊號:ScalaLearning)每天為大家帶來一點Scala語言、Spark、Kafka、Flink、AKKA等大資料技術乾貨及相關技術資訊。技術永無止境,勇攀高峰,一往直前!
覺得文章不錯?掃描關注

這裡寫圖片描述