akka实现的actor
定义一个 Actor 类
要定义自己的Actor类,需要继承 Actor 并实现receive 方法.
receive 方法需要定义一系列 case 语句(类型为 PartialFunction[Any, Unit]) 来描述你的Actor能够处理哪些消息,以及如何进行处理。
如下例:
- import akka.actor.Actor
- import akka.actor.Props
- import akka.event.Logging
- class MyActor extends Actor {
- val log = Logging(context.system, this)
- def receive = {
- case "test" ⇒ log.info("received test")
- case _ ⇒ log.info("received unknown message")
- }
- }
需要提供一个接受的所有消息的模式匹配规则,如果你希望处理未知的消息,你需要象上例一样提供一个缺省的case分支。否则会有一个 akka.actor.UnhandledMessage(message, sender, recipient) 被发布到 Actor系统(ActorSystem)‘的 事件流(EventStream)中。
发送消息
向actor发送消息是使用下列方法之一。
- ! 意思是“fire-and-forget”, e.g. 异步发送一个消息并立即返回。也称为 tell.
- ? 异步发送一条消息并返回一个 Future代表一个可能的回应。也称为 ask.
每一个消息发送者分别保证自己的消息的次序.
Tell: Fire-forget
这是发送消息的推荐方式。 不会阻塞地等待消息。它拥有最好的并发性和可扩展性。
- actor ! "hello"
如果是在一个Actor中调用 ,那么发送方的actor引用会被隐式地作为消息的 sender: ActorRef 成员一起发送. 目的actor可以使用它来向原actor发送回应, 使用 sender ! replyMsg.
如果 不 是从Actor实例发送的, sender成员缺省为 deadLetters actor 引用。
Ask: Send-And-Receive-Future
ask 模式既包含actor也包含future, 所以它是作为一种使用模式,而不是ActorRef的方法:
- import akka.pattern.{ ask, pipe }
- case class Result(x: Int, s: String, d: Double)
- case object Request
- implicit val timeout = Timeout(5 seconds) // 下面的 `?` 会用到
- val f: Future[Result] =
- for {
- x ← ask(actorA, Request).mapTo[Int] // 直接调用
- s ← actorB ask Request mapTo manifest[String] // 隐式转换调用
- d ← actorC ? Request mapTo manifest[Double] // 通过符号名调用
- } yield Result(x, s, d)
- f pipeTo actorD // .. 或 ..
- 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处理消息发生异常时自动完成。
- try {
- val result = operation()
- sender ! result
- } catch {
- case e: Exception ⇒
- sender ! akka.actor.Status.Failure(e)
- throw e
- }
如果一个actor没有完成future, 它会在超时时限到来时过期, 以 AskTimeoutException来结束. 超时的时限是按下面的顺序和位置来获取的:
- 显式指定超时:
- import akka.util.duration._
- import akka.pattern.ask
- val future = myActor.ask("hello")(5 seconds)
- 提供类型为 akka.util.Timeout的隐式参数, 例如,
- import akka.util.duration._
- import akka.util.Timeout
- import akka.pattern.ask
- implicit val timeout = Timeout(5 seconds)
- val future = myActor ? "hello"
参阅 Futures (Scala) 了解更多关于等待和查询future的信息。
Future的onComplete, onResult, 或 onTimeout 方法可以用来注册一个回调,以便在Future完成时得到通知。从而提供一种避免阻塞的方法。
警告
在使用future回调如 onComplete, onSuccess, and onFailure时, 在actor内部你要小心避免捕捉该actor的引用, i.e. 不要在回调中调用该actor的方法或访问其可变状态。这会破坏actor的封装,会引用同步bug和race condition, 因为回调会与此actor一同被并发调度。 不幸的是目前还没有一种编译时的方法能够探测到这种非法访问。 参阅: Actor与共享可变状态
akka实现的actor的更多相关文章
- Akka系列(二):Akka中的Actor系统
前言......... Actor模型作为Akka中最核心的概念,所以Actor在Akka中的组织结构是至关重要,本文主要介绍Akka中Actor系统. 1.Actor系统 Actor作为一种封装状态 ...
- Akka简介与Actor模型
Akka是一个构建在JVM上,基于Actor模型的的并发框架,为构建伸缩性强,有弹性的响应式并发应用提高更好的平台.本文主要是个人对Akka的学习和应用中的一些理解. Actor模型 Akka的核心就 ...
- akka设计模式系列-actor锚定
actor锚定模式是指使用actorSelection对acor进行锚定的设计模式,也可以说是一个对actor的引用技巧.在某些情况下,我们可能需要能够根据Actor的path锚定对应的实例.简单来说 ...
- Akka简介与Actor模型(一)
前言...... Akka是一个构建在JVM上,基于Actor模型的的并发框架,为构建伸缩性强,有弹性的响应式并发应用提高更好的平台.本文主要是个人对Akka的学习和应用中的一些理解. Actor模型 ...
- [翻译]AKKA笔记 - ACTOR生命周期 - 基本 -5
原文地址:http://rerun.me/2014/10/21/akka-notes-actor-lifecycle-basic/ (请注意这了讨论的生命周期并不包括 preRestart 或者pos ...
- [Scala] akka actor编程(一)
Akka基础 Akka笔记之Actor简介 Akka中的Actor遵循Actor模型.你可以把Actor当作是人.这些人不会亲自去和别人交谈.他们只通过邮件来交流. 1. 消息传递 2. 并发 3 ...
- Akka(2):Actor生命周期管理 - 监控和监视
在开始讨论Akka中对Actor的生命周期管理前,我们先探讨一下所谓的Actor编程模式.对比起我们习惯的行令式(imperative)编程模式,Actor编程模式更接近现实中的应用场景和功能测试模式 ...
- Actor模型-Akka
英文原文链接,译文链接,原文作者:Arun Manivannan ,译者:有孚 写过多线程的人都不会否认,多线程应用的维护是件多么困难和痛苦的事.我说的是维护,这是因为开始的时候还很简单,一旦你看到性 ...
- Akka系列---什么是Actor
本文已.Net语法为主,同时写有Scala及Java实现代码 严肃的说,演员是一个广泛的概念,作为外行人我对Actor 模型的定义: Actor是一个系统中参与者的虚拟人物,Actor与Actor之间 ...
随机推荐
- python 获取脚本所在目录
平时写python经常会想获得脚本所在的目录,例如有个文件跟脚本文件放在一个相对的目录位置,那就可以通过脚本文件的目录找到对应的文件,即使以后脚本文件移到其他地方,脚本也基本不需要改动(相对于写死目录 ...
- Bootstrap <基础十九>分页
Bootstrap 支持的分页特性.分页(Pagination),是一种无序列表,Bootstrap 像处理其他界面元素一样处理分页. 分页(Pagination) 下表列出了 Bootstrap 提 ...
- 第十篇.bootstrap轮播
使用bootstrap的轮播插件可以向站点添加滑块,内容可以是图像,内嵌框架,视频或其它任何内容,使用轮播插件需要引入bootstrap.min.js. <div id="carous ...
- sprig里的controller之间的跳转的问题
学习spring的controller,发现controller之间的跳转有些地方搞的不是很清楚,如果通过controller的return语句实现跳转的话,会造成request的丢失:具体怎么回事首 ...
- jquery checkbox实例
<!DOCTYPE html><html> <head><meta charset="utf-8" /><title>& ...
- 使用javaScript实现简单倒计时功能
效果如下: <div class="warp"> <p id="txt">距离”十一“国庆放假还有:</p><br&g ...
- xcode6 使用pch出错解决办法
1down vote If you decide to add a .pch file manually and you want to use Objective-C just like befor ...
- STM32——assert_param(expr)
在STM32的固件库和提供的例程中,到处都可以见到assert_param()的使用.如果打开任何一个例程中的stm32f10x_conf.h文件,就可以看到实际上assert_param是一个宏定义 ...
- iOS开发:正则表达式
语法/字符说明表 值表达 . 匹配除换行符外的任意字符 \w 匹配字母或者数字的字符 \W 匹配任意不是字母或数字的字符 \s 匹配任意的空白符(空格.制表符.换行符) \S ...
- 关于linq to sql类线程同步问题
例如,下面一段代码,当两个线程同时访问时会出现各种由于线程不同步而导致的问题,比如什么DataReader已打开未关闭啊,已经添加了重复的键啊等等. /// <summary> /// 当 ...