在使用Java进行并发编程时须要特别的关注锁和内存原子性等一系列线程问题,而Actor模型内部的状态由它本身维护即它内部数据只能由它本身修改(经过消息传递来进行状态修改),因此使用Actors模型进行并发编程能够很好地避免这些问题,Actor由状态(state)、行为(Behavior)和邮箱(mailBox)三部分组成html
如下经过学生与教师之间的邮件通讯来理解akka中的Actor模型编程
首先先只考虑学生单向发送消息给教师(学生--->教师),以下图:
并发
图解:app
下面再详细的解释每一步骤框架
首先StudentSimulatorApp会先启动JVM并初始化ActorSystem
dom
如上图所示,StudentSimulatorApp的主要工做为:异步
ActorSystem做为顶级Actor,能够建立和中止Actors,甚至可关闭整个Actor环境,
此外Actors是按层次划分的,ActorSystem就比如Java中的Object对象,Scala中的Any,
是全部Actors的根,当你经过ActorSystem的actof方法建立Actor时,实际就是在ActorSystem
下建立了一个子Actor。
可经过如下代码来初始化ActorSystemide
val system = ActorSystem("UniversityMessageSystem")高并发
看看TeacherActor的代理的建立代码ui
val teacherActorRef:ActorRef = system.actorOf(Props[TeacherActor])
你只需经过!方法将QuoteReques消息发送给ActorRef(注意:ActorRef也有个tell方法,其做用就委托回调给!)
techerActorRef!QuoteRequest
等价于teacherActorRef.tell(QuoteRequest, teacherActorRef)
完整StudentSimulatorApp代码
object StudentSimulatorApp extends App{
//初始化ActorSystem
val actorSystem=ActorSystem("UniversityMessageSystem")
//构建teacherActorRef
val teacherActorRef=actorSystem.actorOf(Props[TeacherActor])
//发送消息给TeacherActor
teacherActorRef! QuoteRequest
Thread.sleep (2000)
//关闭 ActorSystem,若是不关闭JVM将不会退出
actorSystem.shutdown()
}
object TeacherProtocol{
case class QuoteRequest() //请求
case class QuoteResponse(quoteString:String) //响应
}
ActorRef将消息处理能力委派给Dispatcher,实际上,当咱们建立ActorSystem和ActorRef时,
Dispatcher和MailBox就已经被建立了
Dispatcher从ActorRef中获取消息并传递给MailBox,Dispatcher封装了一个线程池,以后在
线程池中执行MailBox。
protected[akka] override def registerForExecution(mbox: Mailbox, ...): Boolean = {
...
try {
executorService execute mbox
...
}
看看MailBox的实现,没错,其实现了Runnable接口
private[akka] abstract class Mailbox(val messageQueue: MessageQueue) extends SystemMessageQueue with Runnable
当ActorRef发送消息调用目标Actor的reveive方法时,MailBox中的run方法被执行,接着从消息队列中取出一条消息并传递给Actor处理
class TeacherActor extends Actor {
val quotes = List(
"Moderation is for cowards",
"Anything worth doing is worth overdoing",
"The trouble is you think you have time",
"You never gonna know if you never even try")
def receive = {
case QuoteRequest => {
import util.Random
//从list中随机选出一条消息做为回应(这里只print并没回应学生的请求)
val quoteResponse=QuoteResponse(quotes(Random.nextInt(quotes.size)))
println (quoteResponse)
}
}
}
TeacherActor的receive方法将匹配QuoteRequest消息
AKKA NOTES - ACTOR MESSAGING - 1
Akka框架——第一节:并发编程简介
Akka Quickstart with Scala