Scala的Akka Actor

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/takeuherat/article/details/101671296

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
    }
}
}

猜你喜欢

转载自blog.csdn.net/takeuherat/article/details/101671296