package actor
import akka.actor.{Actor, ActorSystem, Props}
/**
* 当继承actor后,就是一个Actor,核心方法receive 方法重写
*/
class SayHelloActor extends Actor {
/**
* 1. receive 方法,会被Actor的mailbox(实现了Runnable接口)调用
* 2.当该Actor的mailbox 接收到消息,就会调用了receive
* 3.type receive = PartialFunction[Any,Unit]
*
* @return
*/
override def receive: Receive = {
case "hello" => println("收到hello,回应hello too :)")
case "ok" => println("收到ok,回应ok too :)")
case "exit" => {
println("接收到exit,退出系统")
context.stop(self) //停止actorref
context.system.terminate() // 退出actorsystem
}
case _ => println("匹配不到")
}
}
object SayHelloActor {
//1.先创建一个ActorSystem,专门用于创建Actor
val actorFactory = ActorSystem("actorFactory")
//2.创建一个Actor的同时,返回Actor的ActorRef
//Props[SayHelloActor] c创建了一个sayhelloActor实例,使用反射
//“sayhelloactor" 给actor取名
//sayHelloActorRef :Actor就是Props[SayHelloActor] 的ActorRef
//创建的sayhelloRef 被ActorSystem接管
val sayHelloActorRef = actorFactory.actorOf(Props[SayHelloActor], "sayHelloActor")
def main(args: Array[String]): Unit = {
//给SayHelloActor 发消息(邮箱)
sayHelloActorRef ! "hello"
sayHelloActorRef ! "ok"
sayHelloActorRef ! "exit"
}
}
简单来说,Actor通过消息传递的方式与外界通信,而且消息传递是异步的。每个Actor都有一个邮箱,邮箱接收并缓存其他Actor发过来的消息,通过邮箱队列mail queue
来处理消息。Actor一次只能同步处理一个消息,处理消息过程中,除了可以接收消息外不能做任何其他操作。
每个Actor是完全独立的,可以同时执行他们的操作。每个Actor是一个计算实体,映射接收到的消息并执行以下动作:发送有限个消息给其他Actor、创建有限个新的Actor、为下一个接收的消息指定行为。这三个动作没有固定的顺序,可以并发地执行,Actor会根据接收到的消息进行不同的处理。
在Actor系统中包含一个未处理的任务集,每个任务都由三个属性标识:
tag
用以区分系统中的其他任务target
通信到达的地址communication
包含在target
目标地址上的Actor,处理任务时可获取的信息。为简单起见,可见一个任务视为一个消息,在Actor之间传递包含以上三个属性的值的消息。
Actor模型有两种任务调度方式:基于线程的调度、基于事件的调度
因此,可以把系统中所有事物都抽象成为一个Actor:
在一个系统中可以将一个大规模的任务分解为一些小任务,这些小任务可以由多个Actor并发处理,从而减少任务的完成时间。
Actor
模型本身确保处理是按照同步的方式执行的。TicketsActor
会处理其收件箱中的每条消息,注意这里没有复杂的线程或锁,只是一个多线程的处理过程,但Actor
系统会管理线程的使用和分配。
Actor是由状态(state)、行为(behavior)、邮箱(mailbox)三者组成的。
Actor模型描述了一组为避免并发编程的公理: