版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
Scala的Akka Actor
Akka(并发编程模型)
Akka是jvm平台上构建高并发,分布式和容错应用的工具包。使用scala写成,提供java和scala的api
Actor模型
- 对并发编程模型进行了更高的抽象
- 异步、非阻塞、高并发的事件驱动模型
- 轻量级事件处理(1G可容纳百万级别个Actor)
为什么Actor模型是一种处理并发的解决方案?
处理并发编程的核心无非就是保持数据的一致性。但多线程的使用可能导致数据编程脏数据。而单线程性能又太低。Actor的出现解决了这个问题,简化了并发编程,提高了系统性能
Actor之间使用ActorRef进行发消息,只需要将消息(有顺序的)投递到对应Actor中的Mailbox即可(由Dispartcher Message分发到各个Mailbox)。
Actor System负责创建和管理Actor是单例的,而Actor是多例的。
class HelloActor extends Actor{
override def receive:Receive={ //这个返回值是一个偏函数
case "你好帅" => println("说什么实话")
case "丑" => println("...")
case "stop" => {
context.stop(self) //停止ActorRef
context.system.terminate //停止Actor System
sender() ! "我给Test发了一条信息" // sender()代表发送者
}
case _ => println("没法判断")
}
}
object Test{
private val AFactory = ActorSystem("工厂") //apply实现ActorSystem工厂
private val HeFactory = AFactory.actorOf(Props[HelloActor],"hello") //创建HelloActor类的Actor
def main(args:Array[String]):Unit={
HeFactory ! "你好帅" //调用 !这个方法
}
}
服务端与客户端的交互
class Server extends Actor{
override def receive:Receive={
case "start" => "老娘已就绪"
case "你叫啥" => "铁扇公主"
case "你是男是女" => "男"
case "你有男票吗" => "有"
case _ => sender ! "what you say?"
}
}
object Client extends App{
val host:String ="127.0.0.1"
val prot:String ="8878"
val conf = ConfigFactory.parseString(
"""
|akka.actor.provider = "RemoteActorRefProvider"
|akka.remote.netty.tcp.hostname = "$host"
|akka.remote.netty.tcp.port = "$port"
""".stripMargin
)
private val ASys = ActorSystem("Server",conf)
private val serverActor = ASys.actorOf(Props[Server],"server")
serverActor ! "start"
}
class ClientActor extends Actor{
var serverActorRef:ActorSelection = _
override def PreStrat():Unit ={
serverActorRef=context.
actorSelection("akka.tcp://[email protected]:8878/user/shanshan")
}
override def receive:Receive={
case "start" =>"客户端已启动"
case msg:Any => {
serverActorRef ! msg
}
}
object ClientActor extends App{
val host:String ="127.0.0.1"
val prot:String ="8878"
val conf = ConfigFactory.parseString(
"""
|akka.actor.provider = "RemoteActorRefProvider"
|akka.remote.netty.tcp.hostname = "$host"
|akka.remote.netty.tcp.port = "$port"
""".stripMargin
)
private val ASys = ActorSystem("Client",conf)
private val clientActor01 = ASys.actorOf(Props[ClientActor],"shanshan")
clientActor01 ! "start"
while(true){
val question = StdIn.readLine();
clientActor01 ! question
}
}
}