目录
Akka概述
Akka 是 JVM 平台上构建高并发、分布式和容错应用的工具包和运行时。
Akka 用 Scala 语言 写成,同时提供了 Scala 和 JAVA 的开发接口。
Akka 中 Actor 模型
Akka 处理并发的方法基于 Actor 模型。Actor 模 型是作为一个并发模型设计和架构的,
在基于 Actor 的系统里,所有的事物都是 Actor,Actor 与 Actor 之间只能通过消息通信。
Actor 模型处理并发问题的原因
从图中可以看到,Actor 与 Actor 之前只能用消息进行通信,当某一个 Actor 给另外一个 Actor 发消息,消息是有顺序的,只需要将消息投寄的相应的邮箱,至于对方 Actor 怎么处理你的 消息你并不知道,当然你也可等待它的回复。
Actor 是 ActorSystem 创 建 的 , ActorSystem 的 职 责 是 负 责 创 建 并 管 理 其 创 建 的 Actor ,。
ActorSystem 的单例的,一个 JVM 进程中有一个即可,而 Acotr 是多例的。
案列一、自己给自己发送消息
pom文件
<!-- 定义一下常量 -->
<properties>
<encoding>UTF-8</encoding>
<scala.version>2.11.8</scala.version>
<scala.compat.version>2.11</scala.compat.version>
<akka.version>2.4.17</akka.version>
</properties>
<dependencies>
<!-- 添加scala的依赖 -->
<dependency>
<groupId>org.scala-lang</groupId>
<artifactId>scala-library</artifactId>
<version>${scala.version}</version>
</dependency>
<!-- 添加akka的actor依赖 -->
<dependency>
<groupId>com.typesafe.akka</groupId>
<artifactId>akka-actor_${scala.compat.version}</artifactId>
<version>${akka.version}</version>
</dependency>
<!-- 多进程之间的Actor通信 -->
<dependency>
<groupId>com.typesafe.akka</groupId>
<artifactId>akka-remote_${scala.compat.version}</artifactId>
<version>${akka.version}</version>
</dependency>
</dependencies>
<!-- 指定插件-->
<build>
<!-- 指定源码包和测试包的位置 -->
<sourceDirectory>src/main/scala</sourceDirectory>
<testSourceDirectory>src/test/scala</testSourceDirectory>
<plugins>
<!-- 指定编译scala的插件 -->
<plugin>
<groupId>net.alchim31.maven</groupId>
<artifactId>scala-maven-plugin</artifactId>
<version>3.2.2</version>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>testCompile</goal>
</goals>
<configuration>
<args>
<arg>-dependencyfile</arg>
<arg>${project.build.directory}/.scala_dependencies</arg>
</args>
</configuration>
</execution>
</executions>
</plugin>
<!-- maven打包的插件 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.4.3</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>reference.conf</resource>
</transformer>
<!-- 指定main方法 -->
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>cn.sheep.robot.ClientActor</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
逻辑图:
自己给自己发消息代码实现:
import akka.actor.{Actor, ActorSystem, Props}
class HelloActor extends Actor{
// 接受消息的
override def receive: Receive = {
// 接受消息并处理
case "你好帅" => println("竟说实话,我喜欢你这种人!")
case "丑" => println("滚犊子 !")
case "stop" => {
context.stop(self) // 停止自己的actorRef
context.system.terminate() // 关闭ActorSystem
}
}
}
object HelloActor {private val nBFactory = ActorSystem("NBFactory")// 工厂
//根据类HelloActor,创建它对应的ActorRef ,并起名helloActor
private val helloActorRef = nBFactory.actorOf(Props[HelloActor], "helloActor")def main(args: Array[String]): Unit = {
// 给自己发送消息
helloActorRef ! "你好帅"
helloActorRef ! "丑"helloActorRef ! "stop"
}
}
案列二、打PingPong
选手A:
import akka.actor.Actor
class AActor extends Actor{override def receive: Receive = {
case "start" => println("A说:I'm OK !")
case "啪" => {
println("A:那必须滴!")
Thread.sleep(1000)
sender() ! "啪啪"
}
}
}
选手B:
import akka.actor.{Actor, ActorRef}
class BActor(val aa: ActorRef) extends Actor{
// 接受消息的
override def receive: Receive = {
case "start" => {
println(":I'm OK !")
aa ! "啪"
}
case "啪啪" => {
println("你真猛!")
Thread.sleep(1000)
aa ! "啪"
}
}
}
规则:
import akka.actor.{ActorSystem, Props}
object PingPongApp extends App{
// actorSystem
private val pingPongActorSystem = ActorSystem("PingPongActorSystem")// 通过actorSystem创建ActorRef
// 创建AActor
private val aActorRef = pingPongActorSystem.actorOf(Props[AActor], "a")// 创建BActorRef
private val bActorRef = pingPongActorSystem.actorOf(Props(new BActor(aActorRef)), "b")aActorRef ! "start"
bActorRef ! "start"}