定义一个 Actor 类

要定义自己的Actor类,需要继承 Actor 并实现receive 方法.

receive 方法需要定义一系列 case 语句(类型为 PartialFunction[Any, Unit]) 来描述你的Actor能够处理哪些消息,以及如何进行处理。

如下例:

  1. import akka.actor.Actor
  2. import akka.actor.Props
  3. import akka.event.Logging
  4. class MyActor extends Actor {
  5. val log = Logging(context.system, this)
  6. def receive = {
  7. case "test" ⇒ log.info("received test")
  8. case _ ⇒ log.info("received unknown message")
  9. }
  10. }

需要提供一个接受的所有消息的模式匹配规则,如果你希望处理未知的消息,你需要象上例一样提供一个缺省的case分支。否则会有一个 akka.actor.UnhandledMessage(message, sender, recipient) 被发布到 Actor系统(ActorSystem)‘的 事件流(EventStream)中。

发送消息

向actor发送消息是使用下列方法之一。

  • ! 意思是“fire-and-forget”, e.g. 异步发送一个消息并立即返回。也称为 tell.
  • ? 异步发送一条消息并返回一个 Future代表一个可能的回应。也称为 ask.

每一个消息发送者分别保证自己的消息的次序.

Tell: Fire-forget

这是发送消息的推荐方式。 不会阻塞地等待消息。它拥有最好的并发性和可扩展性。

  1. actor ! "hello"

如果是在一个Actor中调用 ,那么发送方的actor引用会被隐式地作为消息的 sender: ActorRef 成员一起发送. 目的actor可以使用它来向原actor发送回应, 使用 sender ! replyMsg.

如果 是从Actor实例发送的, sender成员缺省为 deadLetters actor 引用。

Ask: Send-And-Receive-Future

ask 模式既包含actor也包含future, 所以它是作为一种使用模式,而不是ActorRef的方法:

  1. import akka.pattern.{ ask, pipe }
  2. case class Result(x: Int, s: String, d: Double)
  3. case object Request
  4. implicit val timeout = Timeout(5 seconds) // 下面的 `?` 会用到
  5. val f: Future[Result] =
  6. for {
  7. x ← ask(actorA, Request).mapTo[Int] // 直接调用
  8. s ← actorB ask Request mapTo manifest[String] // 隐式转换调用
  9. d ← actorC ? Request mapTo manifest[Double] // 通过符号名调用
  10. } yield Result(x, s, d)
  11. f pipeTo actorD // .. 或 ..
  12. pipe(f) to actorD

上面的例子展示了将 ask 与 future上的 pipeTo 模式一起使用,因为这是一种非常常用的组合。 请注意上面所有的调用都是完全非阻塞和异步的: ask 产生 Future, 三个Future通过for-语法组合成一个新的Future,然后用 pipeTo 在future上安装一个 onComplete-处理器来完成将收集到的 Result 发送到其它actor的动作。

使用 ask 将会象 tell 一样发送消息给接收方, 接收方必须通过 sender ! reply 发送回应来为返回的 Future 填充数据. ask 操作包括创建一个内部actor来处理回应,必须为这个内部actor指定一个超时期限,过了超时期限内部actor将被销毁以防止内存泄露。

如果要以异常来填充future你需要发送一个 Failure 消息给发送方。这个操作不会在actor处理消息发生异常时自动完成。

  1. try {
  2. val result = operation()
  3. sender ! result
  4. } catch {
  5. case e: Exception ⇒
  6. sender ! akka.actor.Status.Failure(e)
  7. throw e
  8. }

如果一个actor没有完成future, 它会在超时时限到来时过期, 以 AskTimeoutException来结束. 超时的时限是按下面的顺序和位置来获取的:

  1. 显式指定超时:
  1. import akka.util.duration._
  2. import akka.pattern.ask
  3. val future = myActor.ask("hello")(5 seconds)
  1. 提供类型为 akka.util.Timeout的隐式参数, 例如,
  1. import akka.util.duration._
  2. import akka.util.Timeout
  3. import akka.pattern.ask
  4. implicit val timeout = Timeout(5 seconds)
  5. val future = myActor ? "hello"

参阅 Futures (Scala) 了解更多关于等待和查询future的信息。

FutureonComplete, onResult, 或 onTimeout 方法可以用来注册一个回调,以便在Future完成时得到通知。从而提供一种避免阻塞的方法。

警告

在使用future回调如 onComplete, onSuccess, and onFailure时, 在actor内部你要小心避免捕捉该actor的引用, i.e. 不要在回调中调用该actor的方法或访问其可变状态。这会破坏actor的封装,会引用同步bug和race condition, 因为回调会与此actor一同被并发调度。 不幸的是目前还没有一种编译时的方法能够探测到这种非法访问。 参阅: Actor与共享可变状态

akka实现的actor的更多相关文章

  1. Akka系列(二):Akka中的Actor系统

    前言......... Actor模型作为Akka中最核心的概念,所以Actor在Akka中的组织结构是至关重要,本文主要介绍Akka中Actor系统. 1.Actor系统 Actor作为一种封装状态 ...

  2. Akka简介与Actor模型

    Akka是一个构建在JVM上,基于Actor模型的的并发框架,为构建伸缩性强,有弹性的响应式并发应用提高更好的平台.本文主要是个人对Akka的学习和应用中的一些理解. Actor模型 Akka的核心就 ...

  3. akka设计模式系列-actor锚定

    actor锚定模式是指使用actorSelection对acor进行锚定的设计模式,也可以说是一个对actor的引用技巧.在某些情况下,我们可能需要能够根据Actor的path锚定对应的实例.简单来说 ...

  4. Akka简介与Actor模型(一)

    前言...... Akka是一个构建在JVM上,基于Actor模型的的并发框架,为构建伸缩性强,有弹性的响应式并发应用提高更好的平台.本文主要是个人对Akka的学习和应用中的一些理解. Actor模型 ...

  5. [翻译]AKKA笔记 - ACTOR生命周期 - 基本 -5

    原文地址:http://rerun.me/2014/10/21/akka-notes-actor-lifecycle-basic/ (请注意这了讨论的生命周期并不包括 preRestart 或者pos ...

  6. [Scala] akka actor编程(一)

    Akka基础 Akka笔记之Actor简介  Akka中的Actor遵循Actor模型.你可以把Actor当作是人.这些人不会亲自去和别人交谈.他们只通过邮件来交流.  1. 消息传递 2. 并发 3 ...

  7. Akka(2):Actor生命周期管理 - 监控和监视

    在开始讨论Akka中对Actor的生命周期管理前,我们先探讨一下所谓的Actor编程模式.对比起我们习惯的行令式(imperative)编程模式,Actor编程模式更接近现实中的应用场景和功能测试模式 ...

  8. Actor模型-Akka

    英文原文链接,译文链接,原文作者:Arun Manivannan ,译者:有孚 写过多线程的人都不会否认,多线程应用的维护是件多么困难和痛苦的事.我说的是维护,这是因为开始的时候还很简单,一旦你看到性 ...

  9. Akka系列---什么是Actor

    本文已.Net语法为主,同时写有Scala及Java实现代码 严肃的说,演员是一个广泛的概念,作为外行人我对Actor 模型的定义: Actor是一个系统中参与者的虚拟人物,Actor与Actor之间 ...

随机推荐

  1. 也谈自动化平台的搭建,另附高大上的名字---无人值守定时巡检系统(selenium+testng+ant+jenkins)

    最近公司新项目改版,由于没有运维,开发则负责上线任务,并且都是手动上线,并行的项目多了,分支混乱,经常导致B项目上线覆盖A项目,导致系统不定时出现异常,老板知道了便扣了大家的绩效,作为测试这边必须想个 ...

  2. 《JavaScript高级程序设计》读书笔记--(2)基本概念

    变量 Javascript 是区分大小写的, 也就是说 var nun 与 var Num 是不同的变量. ECMAScript的变量是松散类型的,所谓松散类型就是可以保存任何类型的数据.ECMASc ...

  3. 第二篇.Bootstrap起步

    第二篇Bootstrap起步 我们可以在http://getbootstrap.com下载bootstrap的文件 点击左边的download bootstrap可以下载bootstrap的css,j ...

  4. cURL入门

    cURL 是一个利用URL语法规定来传输文件和数据的工具,支持很多协议,如HTTP.FTP.TELNET等.最爽的是,PHP也支持 cURL 库.本文将介绍 cURL 的一些高级特性,以及在PHP中如 ...

  5. 浅谈c语言的指针

    对于非计算机专业的同学,c语言的指针往往就是老师的一句“指针不考“就带过了.c语言的指针号称是c语言的灵魂,是c语言中最精妙的部分. 指针本质上也是变量,也就是一段内存,只是他的特殊之处是他存储的数据 ...

  6. centos添加硬盘

    fdisk -l ## 这里是查看目前系统上有几块硬盘 Disk /dev/sda: 36.4 GB, 36401479680 bytes 255 heads, 63 sectors/track, 4 ...

  7. Pegasos: Primal Estimated sub-GrAdient Solver for SVM

    Abstract We describe and analyze a simple and effective iterative algorithm for solving the optimiza ...

  8. 移动测试主要使用的测试框架,基于python

    1.uiautomator google自己的测试框架,可以跨应用测试, 语言支持java,python也可以在GitHub上找到封装的包,去调用uiautomator. 2.Robotium jav ...

  9. [SHELL] 修改xml的内容

    解析和修改xml用python比较方便,但如果不方便使用python,可以用sed命令简单替换 例如,欲替换下面一行中的端口号的值: <param name="ftpPort" ...

  10. sphinx,coreseek安装

    sphinx是国外的一款搜索软件. coreseek是在sphinx的基础上,增加了中文分词功能,换句话说,就是支持了中文. Coreseek发布了3.2.14版本和4.1版本,其中的3.2.14版本 ...