oa考勤管理系统解决方案,考勤系统操作流程
542
2022-05-30
Akka 中Actor 模型是一种处理并发问题的解决方案
Actor模型工作机制说明
1 处理并发问题关键是要保证共享数据的一致性和正确性,因为程序是多线程时,多个线程对同一个数据进行修改,若不加同步条件,势必会造成数据污染 但是当对关键代码加入同步条件synchronized 后,实际上大并发就会阻塞在这段代码,对程序效率有影响 2 若是用单线程处理,不会有数据一致性的问题,但是系统的性能又不能保证。 3 Actor 模型是一种处理并发问题的解决方案 4 Actor 之间只能用消息进行通信,给 Actor发消息,消息是有顺序的(消息队列),只需要将消息投寄的相应的邮箱即可。 5 怎么处理消息是由接收消息的Actor决定的,发送消息Actor可以等待回复,也可以异步处理【类似ajax异步】 6 ActorSystem 的职责是负责创建并管理其创建的 Actor, ActorSystem 是单例的(ActorSystem是一个工厂,专门创建Actor),一个 JVM 进程中有一个即可,而 Acotr 是可以有多个的 7 Actor模型是对并发模型进行了更高的抽象。 8 Actor模型是异步、非阻塞、高性能的事件驱动编程模型 9 Actor模型是轻量级事件处理(1GB 内存可容纳百万级别个 Actor),因此处理大并发性能高.
Actor模型工作机制
1 ActorySystem创建Actor 2 ActorRef:可以理解成是Actor的代理或者引用。 (注:消息是通过ActorRef来发送,而不能通过Actor 发送消息,通过哪个ActorRef 发消息,就表示把该消息发给哪个Actor) 3 消息发送到Dispatcher Message (消息分发器),它得到消息后,会将消息进行分发到对应的MailBox。 (注: Dispatcher Message 可以理解成是一个线程池, MailBox 可以理解成是消息队列,可以缓冲多个消息,遵守FIFO 先进先出原则) 4 Actor 可以通过 receive方法来获取消息,然后进行处理。
Actor间传递消息机制
1 每一个消息就是一个Message对象。Message 继承了Runable, 因为Message就是线程类。 2 编程时只需要编写Actor就可以了,其它的交给Actor模型完成即可。 3 A Actor要给B Actor 发送消息,那么A Actor 要先拿到(也称为持有) B Actor 的 代理对象ActorRef 才能发送消息 4 每个actor有个mailbox(封装不可见)且实现了runnable 接口一直在运行,等待其他人给发消息
//1. 当我们继承Actor后,就是一个Actor,核心方法receive 方法重写 class HelloActor extends Actor{ //1. receive方法,会被该Actor的MailBox(实现了Runnable接口)调用 //2. 当该Actor的MailBox 接收到消息,就会调用 receive //3. type Receive = PartialFunction[Any, Unit] override def receive: Actor.Receive = { case "hello" => println("收到hello, 回应hello too:)") case "ok" => println("收到ok, 回应ok too:)") case "exit" => { println("接收到exit指令,退出系统") context.stop(self) //停止actoref (停止mailbox) // self 就是自己 context.system.terminate()//退出actorsystem (停止 actor ) } case _ => println("匹配不到") } } object HelloActorDemo{ //先创建一个ActorSystem, 专门用于创建Actor //1. ActorSystem apply方法返回一个 ActorSystem; val actoryFactory = ActorSystem("ActoryFactory") //2. 创建一个Actor的同时,返回Actor的ActorRef 说明 //(1) Props[SayHelloActor] 创建了一个 SayHelloActor实例,使用反射 ,也可以使用 new 方式 // Props[SayHelloActor] 该实例被 ActorSystem 接管了 //(2) "alexHelloActor" 给actor取名 //(3) sayHelloActorRef: ActorRef 就是 Props[SayHelloActor] 的ActorRef //(4) 创建的SayHelloActor(Props[SayHelloActor]) 实例被ActorSystm接管 //(5) ActorRef 仅仅是与SayHelloActor(Props[SayHelloActor]) 关联起来 private val alexHelloActor1: ActorRef = actoryFactory.actorOf(Props[HelloActor], "alexHelloActor") def main(args: Array[String]): Unit = { alexHelloActor1 ! "hello" alexHelloActor1 ! "ok" alexHelloActor1 ! "exit" } }
Actor自我通讯机制原理图 当程序执行 aActorRef = actorFactory.actorOf(Props[AActor], "aActor") ,会完成如下任务 1 actorFactory 是 ActorSystem("ActorFactory") 这样创建的。 2 这里的 Props[AActor] 会使用反射机制,创建一个AActor 对象,如果是actorFactory.actorOf(Props(new AActor(bActorRef)), "aActorRef") 形式,就是使用new 的方式创建一个AActor对象, 注意Props() 是小括号。 3 会创建一个AActor 对象的代理对象 aActorRef , 使用aActorRef 才能发送消息 4 会在底层创建 Dispather Message ,是一个线程池,用于分发消息, 消息是发送到对应的Actor的 MailBox 5 会在底层创建AActor 的MailBox 对象,该对象是一个队列,可接收Dispatcher Message 发送的消息 6 MailBox 实现了Runnable 接口,是一个线程,一直运行并调用Actor的receive 方法,因此当Dispather 发送消息到MailBox时,Actor 在receive 方法就可以得到信息. 7 aActorRef ! "hello", 表示把hello消息发送到A Actor 的mailbox (通过Dispatcher Message 转发)
object ActorsGame { def main(args: Array[String]): Unit = { //创建ActorSystem val actorFactory = ActorSystem("actorFactory") // 创建 bobref val bobActoref = actorFactory.actorOf(Props[BobActor], "bobActor") // 创建 alexref val alexActoref = actorFactory.actorOf(Props(new AlexActor(bobActoref)), "alexActor") alexActoref ! "start" } } // 构建 AlexActor 重写receive时候,传入bobref ,这样 alex才能给Bob 发信 class AlexActor (actorref: ActorRef) extends Actor { val bobref: ActorRef = actorref override def receive: Receive = { case "start" => { println("给自己发消息,开始沟通Bob") self ! "hello" } case "hello" => { println("准备给Bob 发消息 ") // 必须持有bobref Thread.sleep(1000) bobref ! "hello Bob san" // 发消息 } case "hello alex san" =>{ println("收到Bob 发的消息") self ! "hello" } } } class BobActor extends Actor { override def receive: Receive = { case "hello Bob san" => { println("接到 alex 发的消息") Thread.sleep(1000) sender() ! "hello alex san" //通过sender() 可以获取到发现消息的actor的ref } } }
Scala
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。