抛开复杂的业务逻辑,让我们从一个超级简单的例子学习Akka Actor的用法。 Scala cookbook的作者Alvin Alexander在他的网站上提供了两个例子。
本文翻译、整理于他的两篇文章。
下面几行代码就实现了一个actor。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 
  | import akka.actor.Actor import akka.actor.ActorSystem import akka.actor.Props   class HelloActor extends Actor {   def receive = {     case "hello" => println("您好!")     case _       => println("您是?")   } }   object Main extends App {   val system = ActorSystem("HelloSystem")      val helloActor = system.actorOf(Props[HelloActor], name = "helloactor")   helloActor ! "hello"   helloActor ! "喂" } 
  | 
- 1到3行是引入必要的类
 - 第5行定义了一个Actor, 实现了receive方法, 如果接收到"hello",返回一个礼貌性的"您好", 如果接收到其它消息,返回"您是?"
 - 第12行定义了一个main对象
 - 我们需要一个ActorSystem,所以在第13行创建了一个
 - 第15行创建了一个HellActor的实例,返回结果类型为ActorRef。 这里HelloActor我们调用默认的构造函数,你也可以调用特定的带参数的构造函数
 - 第16,17行我们发送了两个消息给这个actor, actor应该能收到这两条消息并处理
 
!是一个简化发送消息的操作符, ScalaActorRef为ActorRef定义的一个隐式方法。
1 2 3 
  | trait ScalaActorRef { ref: ActorRef ⇒   def !(message: Any)(implicit sender: ActorRef = null): Unit } 
  | 
假定你已经安装了scala和sbt。创建一个文件夹,在此文件夹中新建一个build.sbt,内容如下:
1 2 3 4 5 
  | name := "Hello Test #1"  version := "1.0"  scalaVersion := "2.11.4"   libraryDependencies += "com.typesafe.akka" %% "akka-actor" % "2.3.9" 
  | 
我机器上安装scala的版本为2.11.4,你可以调整为你机器上合适的版本,以及相应的akka的版本。
将上述actor的代码复制到此文件夹下的HelloActor.scala文件中。
执行下面的命令:
输出结果
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 
  | C:\akka>sbt run [info] Set current project to Hello Test  [info] Updating {file:/C:/akka/}akka... [info] Resolving org.scala-lang   [info] Resolving com.typesafe.akka   [info] Resolving org.scala-lang   [info] Resolving com.typesafe   [info] Resolving org.scala-lang   [info] Resolving org.scala-lang   [info] Resolving org.scala-lang.modules   [info] Resolving org.scala-lang.modules .   [info] Resolving jline [info] Done updating. [warn] Scala version was updated by one of library dependencies: [warn]  * org.scala-lang:scala-library:2.11.4 -> 2.11.5 [warn] To force scalaVersion, add the following: [warn]  ivyScala := ivyScala.value map { _.copy(overrideScalaVersion = true) } [warn] Run 'evicted' to see detailed eviction warnings [info] Running Main 您好! 您是? 
  | 
Ctrl + C可以终止程序的运行。
这里还有一个更复杂的例子,涉及到两个actor的交互。 就像两个人在乒乒乓乓的打乒乓球。 两个actor来回的ping pang,直到达到特定的次数才停止。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 
  | import akka.actor._   case object PingMessage case object PongMessage case object StartMessage case object StopMessage   class Ping(pong: ActorRef) extends Actor {   var count = 0   def incrementAndPrint { count += 1; println("ping") }   def receive = {     case StartMessage =>         incrementAndPrint         pong ! PingMessage     case PongMessage =>                 if (count > 9) {           sender ! StopMessage           println("ping stopped")           context.stop(self)         } else { 		  incrementAndPrint           sender ! PingMessage         }   } }   class Pong extends Actor {   def receive = {     case PingMessage =>         println("  pong")         sender ! PongMessage     case StopMessage =>         println("pong stopped")         context.stop(self) 		context.system.shutdown()   } }   object PingPongTest extends App {   val system = ActorSystem("PingPongSystem")   val pong = system.actorOf(Props[Pong], name = "pong")   val ping = system.actorOf(Props(new Ping(pong)), name = "ping")      ping ! StartMessage } 
  | 
这里定义了两个actor: Ping和Pang。
- Ping 接收StartMessage和 PongMessage。 StartMessage是一个启动消息,由main对象发送,PongMessage来自Pong actor,如果次数还未达到,它继续发送PingMessage。
 - Pong 接收StopMessage和 PingMessage。 如果接收到PingMessage,它就发送一个PongMessage, 如果是StopMessage, 停止ActorSystem
 
这里调用了Ping的带参数的构造函数 Props(new Ping(pong))
参考文档