本节主要内容:
1. 停止Actor

1. 停止Actor

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

  1. /*
  2. *停止Actor:ActorSystem.shutdown方法
  3. */
  4. object Example_10 extends App{
  5. import akka.actor.Actor
  6. import akka.actor.ActorSystem
  7. import akka.actor.Props
  8. class FirstActor extends Actor with ActorLogging{
  9. var child:ActorRef = context.actorOf(Props[MyActor], name = "myActor")
  10. def receive = {
  11. //向MyActor发送消息
  12. case x => child ! x;log.info("received "+x)
  13. }
  14. override def postStop(): Unit = {
  15. log.info("postStop In FirstActor")
  16. }
  17. }
  18. class MyActor extends Actor with ActorLogging{
  19. def receive = {
  20. case "test" => log.info("received test");
  21. case _ => log.info("received unknown message");
  22. }
  23. override def postStop(): Unit = {
  24. log.info("postStop In MyActor")
  25. }
  26. }
  27. val system = ActorSystem("MyActorSystem")
  28. val systemLog=system.log
  29. //创建FirstActor对象
  30. val firstactor = system.actorOf(Props[FirstActor], name = "firstActor")
  31. systemLog.info("准备向firstactor发送消息")
  32. //向firstactor发送消息
  33. firstactor!"test"
  34. firstactor! 123
  35. //关闭ActorSystem,停止所有Acotr运行
  36. system.shutdown()
  37. }

代码运行结果:

  1. [INFO] [04/02/2016 21:51:34.440] [main] [ActorSystem(MyActorSystem)] 准备向firstactor发送消息
  2. [INFO] [04/02/2016 21:51:34.441] [MyActorSystem-akka.actor.default-dispatcher-4] [akka://MyActorSystem/user/firstActor/myActor] received test
  3. [INFO] [04/02/2016 21:51:34.441] [MyActorSystem-akka.actor.default-dispatcher-2] [akka://MyActorSystem/user/firstActor] received test
  4. [INFO] [04/02/2016 21:51:34.441] [MyActorSystem-akka.actor.default-dispatcher-2] [akka://MyActorSystem/user/firstActor] received 123
  5. [INFO] [04/02/2016 21:51:34.441] [MyActorSystem-akka.actor.default-dispatcher-4] [akka://MyActorSystem/user/firstActor/myActor] received unknown message
  6. [INFO] [04/02/2016 21:51:34.446] [MyActorSystem-akka.actor.default-dispatcher-4] [akka://MyActorSystem/user/firstActor/myActor] postStop In MyActor
  7. [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的运行

  1. /*
  2. *停止Actor:context.stop方法
  3. */
  4. object Example_11 extends App{
  5. import akka.actor.Actor
  6. import akka.actor.ActorSystem
  7. import akka.actor.Props
  8. class FirstActor extends Actor with ActorLogging{
  9. var child:ActorRef = context.actorOf(Props[MyActor], name = "myActor")
  10. def receive = {
  11. case "stop"=>context.stop(child)
  12. case x =>{
  13. //向MyActor发送消息
  14. child ! x
  15. log.info("received "+x)
  16. }
  17. }
  18. override def postStop(): Unit = {
  19. log.info("postStop In FirstActor")
  20. }
  21. }
  22. class MyActor extends Actor with ActorLogging{
  23. def receive = {
  24. case "test" => log.info("received test");
  25. case _ => log.info("received unknown message");
  26. }
  27. override def postStop(): Unit = {
  28. log.info("postStop In MyActor")
  29. }
  30. }
  31. val system = ActorSystem("MyActorSystem")
  32. val systemLog=system.log
  33. //创建FirstActor对象
  34. val firstactor = system.actorOf(Props[FirstActor], name = "firstActor")
  35. systemLog.info("准备向firstactor发送消息")
  36. //向firstactor发送消息
  37. firstactor!"test"
  38. firstactor! 123
  39. firstactor!"stop"
  40. }

代码运行结果:

  1. [INFO] [04/02/2016 22:02:48.760] [main] [ActorSystem(MyActorSystem)] 准备向firstactor发送消息
  2. [INFO] [04/02/2016 22:02:48.761] [MyActorSystem-akka.actor.default-dispatcher-5] [akka://MyActorSystem/user/firstActor/myActor] received test
  3. [INFO] [04/02/2016 22:02:48.761] [MyActorSystem-akka.actor.default-dispatcher-2] [akka://MyActorSystem/user/firstActor] received test
  4. [INFO] [04/02/2016 22:02:48.762] [MyActorSystem-akka.actor.default-dispatcher-2] [akka://MyActorSystem/user/firstActor] received 123
  5. [INFO] [04/02/2016 22:02:48.762] [MyActorSystem-akka.actor.default-dispatcher-5] [akka://MyActorSystem/user/firstActor/myActor] received unknown message
  6. [INFO] [04/02/2016 22:02:48.763] [MyActorSystem-akka.actor.default-dispatcher-5] [akka://MyActorSystem/user/firstActor/myActor] postStop In MyActor

代码的重点为

  1. class FirstActor extends Actor with ActorLogging{
  2. var child:ActorRef = context.actorOf(Props[MyActor], name = "myActor")
  3. def receive = {
  4. case "stop"=>context.stop(child)
  5. case x =>{
  6. //向MyActor发送消息
  7. child ! x
  8. log.info("received "+x)
  9. }
  10. }
  11. override def postStop(): Unit = {
  12. log.info("postStop In FirstActor")
  13. }
  14. }

中的case “stop”=>context.stop(child),直接通过context.stop方法停止Actor的运行。注意程序中并没有使用system.shutdown方法,因此整个程序的不会停止,如下图所示
Akka并发编程——第五节:Actor模型(四) - 图1
(3)通过akka.actor.PoisonPill消息停止Actor的运行

  1. /*
  2. *停止Actor:使用akka.actor.PoisonPill
  3. */
  4. object Example_12 extends App{
  5. import akka.actor.Actor
  6. import akka.actor.ActorSystem
  7. import akka.actor.Props
  8. import akka.actor.PoisonPill
  9. class FirstActor extends Actor with ActorLogging{
  10. var child:ActorRef = context.actorOf(Props[MyActor], name = "myActor")
  11. def receive = {
  12. //向child发送PoisonPill停止其运行
  13. case "stop"=>child!PoisonPill
  14. case x =>{
  15. //向MyActor发送消息
  16. child ! x
  17. log.info("received "+x)
  18. }
  19. }
  20. override def postStop(): Unit = {
  21. log.info("postStop In FirstActor")
  22. }
  23. }
  24. class MyActor extends Actor with ActorLogging{
  25. def receive = {
  26. case "test" => log.info("received test");
  27. case _ => log.info("received unknown message");
  28. }
  29. override def postStop(): Unit = {
  30. log.info("postStop In MyActor")
  31. }
  32. }
  33. val system = ActorSystem("MyActorSystem")
  34. val systemLog=system.log
  35. //创建FirstActor对象
  36. val firstactor = system.actorOf(Props[FirstActor], name = "firstActor")
  37. systemLog.info("准备向firstactor发送消息")
  38. //向firstactor发送消息
  39. firstactor!"test"
  40. firstactor! 123
  41. firstactor!"stop"
  42. }

代码运行结果:

  1. [INFO] [04/02/2016 22:12:09.947] [main] [ActorSystem(MyActorSystem)] 准备向firstactor发送消息
  2. [INFO] [04/02/2016 22:12:09.947] [MyActorSystem-akka.actor.default-dispatcher-2] [akka://MyActorSystem/user/firstActor/myActor] received test
  3. [INFO] [04/02/2016 22:12:09.947] [MyActorSystem-akka.actor.default-dispatcher-4] [akka://MyActorSystem/user/firstActor] received test
  4. [INFO] [04/02/2016 22:12:09.947] [MyActorSystem-akka.actor.default-dispatcher-4] [akka://MyActorSystem/user/firstActor] received 123
  5. [INFO] [04/02/2016 22:12:09.947] [MyActorSystem-akka.actor.default-dispatcher-2] [akka://MyActorSystem/user/firstActor/myActor] received unknown message
  6. [INFO] [04/02/2016 22:12:09.951] [MyActorSystem-akka.actor.default-dispatcher-4] [akka://MyActorSystem/user/firstActor/myActor] postStop In MyActor

代码与Exampel_11中的不同之处在于

  1. //向child发送PoisonPill停止其运行
  2. case "stop"=>child!PoisonPill

它使用不是context.stop方法,而是向MyActor发送了PoisonPill消息,其它代码不变。
还有一种gracefulStop方法可以停止Actor的运行,这部分内容等了解完Future类的作用原理之后再来讨论