While模式严格来说是while循环在Akka中的合理实现。while是开发过程中经常用到的语句之一,也是绝大部分编程语言都支持的语法。但while语句是一个循环,如果循环条件没有达到会一直执行while语句体的代码,且会阻塞while语句外的代码。如果在Akka中简单的使用while语句会极大的限制当前actor的功能。

object GeneralWhile {
def main(args: Array[String]): Unit = {
var i=0
val maxLine = 10
while(i<maxLine){
println(i)
i += 1
}
}
}

输出:

0
1
2
3
4
5
6
7
8
9

  上图是while语句的常规用法,打印了从0-9的数字。如果这段代码出现在了actor对某个消息的处理过程中,就会带来其他的问题和不便。

class WhileActor extends Actor{
override def receive: Receive = {
case "start" =>
println("do start work")
var i=0
val maxLine = 10
while(i<maxLine){
println(i)
i += 1
}
println("start work done")
case "others" =>
println("do other work")
}
}
object WhilePattern1 {
def main(args: Array[String]): Unit = {
val system = ActorSystem("WhilePattern1",ConfigFactory.load())
val whileActor = system.actorOf(Props(new WhileActor),"WhilePattern1")
whileActor ! "start"
whileActor ! "others"
}
}

输出:

do start work
0
1
2
3
4
5
6
7
8
9
start work done
do other work

  上面代码是actor中简单使用while的例子。其实在简单的业务场景下,这种实现并没有太大问题,只不过while可能会阻塞当前actor而已。不过while有一个极端的情况,那就是while死循环。虽然死循环不能轻易出现,不过也非常有用。比如有以下场景:循环读取数据库做某种操作。在Akka的消息处理过程中是绝对不能出现死循环的,一旦出现死循环这个actor基本就废了(因为阻塞到了这个方法处理)!

  其实如果你的业务需求需要在Akka中使用死循环,而且你也的确这么用了,那只能说明对Actor模型不熟悉,因为Actor模型本身对消息的处理就是“死循环”。为什么说actor本身就是一个“死循环"呢?actor在收到消息会进行对应的处理,死循环也就意味着一直收到消息,那么如何一直收到消息呢?其他actor给它发消息或者自己给自己发消息,很显然,actor内部的循环逻辑跟其他actor关系不大,发消息给自己是比较合理的。

  

class WhileForeverActor extends Actor{
var condition = true
override def preStart(): Unit = {
super.preStart()
self ! "doWork"
}
override def receive: Receive = {
case "doWork" =>
println("从数据库获取n条数据循环处理")
Thread.sleep(1000)
println("处理完毕")
if(condition){
self ! "doWork"
}
case "otherWork" =>
println("处理其他消息")
}
}
object WhilePattern2 {
def main(args: Array[String]): Unit = {
val system = ActorSystem("WhilePattern2",ConfigFactory.load())
val whileActor: ActorRef = system.actorOf(Props(new WhileForeverActor),"WhilePattern2")
Thread.sleep(3*1000)
whileActor ! "otherWork"
whileActor ! "otherWork"
}
}

输出:

从数据库获取n条数据循环处理
处理完毕
从数据库获取n条数据循环处理
处理完毕
从数据库获取n条数据循环处理
处理完毕
处理其他消息
处理其他消息
从数据库获取n条数据循环处理
处理完毕
从数据库获取n条数据循环处理
处理完毕
从数据库获取n条数据循环处理
处理完毕
从数据库获取n条数据循环处理

  上面是Akka中的while模式。简单点说,就是用自身消息驱动acotor的循环处理。这样做的好处就是可以在某次循环结束后及时的处理其他类型的消息,而不至于阻塞当前的actor,而且可以随时通过发消息的形式中断循环或修改循环条件。

   本文介绍了Akka中的while设计模式,该模式虽然简单,但也都是Akka初学者经常会遇到也最容易设计不当的情形。希望大家好好掌握该设计模式,设计出更优秀的代码。

akka设计模式系列-While模式的更多相关文章

  1. akka设计模式系列-Chain模式

    链式调用在很多框架和系统中经常存在,算不得上是我自己总结的设计模式,此处只是简单介绍在Akka中的两种实现方式.我在这边博客中简化了链式调用的场景,简化后也更符合Akka的设计哲学. trait Ch ...

  2. akka设计模式系列-Backend模式

    上一节我们介绍了Akka使用的基本模式,简单点来说就是,发消息给actor,处理结束后返回消息.但这种模式有个缺陷,就是一旦某个消息处理的比较慢,就会阻塞后面所有消息的处理.那么有没有方法规避这种阻塞 ...

  3. akka设计模式系列-Aggregate模式

    所谓的Aggregate模式,其实就是聚合模式,跟masterWorker模式有点类似,但其出发点不同.masterWorker模式是指master向worker发送命令,worker完成某种业务逻辑 ...

  4. akka设计模式系列-基础模式

    本文介绍akka的基本使用方法,由于属于基础功能,想不出一个很高大上的名称,此处就以基础模式命名.下文会介绍actor的使用方法,及其优劣点. class SimpleActor(name:Strin ...

  5. akka设计模式系列-慎用ask

    慎用ask应该是Akka设计的一个准则,很多时候我们应该禁用ask.之所以单独把ask拎出来作为一篇博文,主要是akka的初学者往往对ask的使用比较疑惑. "Using ask will ...

  6. akka设计模式系列-消息模型(续)

    在之前的akka设计模式系列-消息模型中,我们介绍了akka的消息设计方案,但随着实践的深入,发现了一些问题,这里重新梳理一下设计方法,避免之前的错误.不当的观点给大家带来误解. 命令和事件 我们仍然 ...

  7. akka设计模式系列

    由于本人爱好Scala,顺便也就爱好Akka,但目前网上对Akka的介绍大多都是概念上或技术方向上的介绍,基本没有Akka设计模式或者Actor模型设计模式的资料.这对于Akka的普及非常不利,因为即 ...

  8. PHP设计模式系列 - 外观模式

    外观模式 通过在必需的逻辑和方法的集合前创建简单的外观接口,外观设计模式隐藏了调用对象的复杂性. 外观设计模式和建造者模式非常相似,建造者模式一般是简化对象的调用的复杂性,外观模式一般是简化含有很多逻 ...

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

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

随机推荐

  1. Cyclic Nacklace HDU - 3746 (kmp next数组应用)

    题目大意 给出字符串,寻找最小要补全的字符个数,使得字符串是两次的循环 解法 通过寻找规律,我们又发现了len-next[len]又派上了用场 ①如果next[len]是0,说明最大前缀后缀和为0,那 ...

  2. Datatable 导出到execl 官网demo

    <!DOCTYPE html> <html> <head> <meta http-equiv="Content-type" content ...

  3. jQuery选择器及常见操作

    jQuery http://jquery.cuishifeng.cn/ 模块 <=>类库 DOM/BOM/JavaScript的类库 版本: 1.x 1.12 2.x 3.x 转换: jq ...

  4. PyCharm开发GUI之PyQt安装

    开发环境 PyCharm 2018.3.3python3.7 1 安装pyqt5 pip install PyQt5-tools 2 配置PyCharm 2.1 配置设计器 其中,program为C: ...

  5. Bazinga HDU 5510 Bazinga(双指针)

    Bazinga HDU 5510 Bazinga(双指针) 题链 解法:对于串i来说,如果串i是不符合的,那么代表串i之前的字符串都是i的子串,那么我们求一个新的i(定义为ti),如果i是ti 的子串 ...

  6. IDEA下tomcat中web项目乱码,控制台乱码解决指南

    若是由于过滤器,request ,response等原因,不适用. 原文作者:http://www.kafeitu.me/tools/2013/03/26/intellij-deal-chinese- ...

  7. HDU 5291 Candy Distribution

    Candy Distribution Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Other ...

  8. vue.js定义一个一级的路由 ----由浅入深

    #### 定义一个路由- 实例化一个路由并设置路由映射表 - 实例化里面第一个参数 routes 路由映射表 - routes 里面参数 - path 路由的路径 - component 路由对应的组 ...

  9. ssh整合配置文件------web.xml配置

    <?xml version="1.0" encoding="UTF-8"?><web-app xmlns:xsi="http://w ...

  10. jQuery动态添加表格1

    用jquery的append方法在指定行的后面新增一行tr,会把新增的行的html追加到指定行的html里面 content +="<tr><td>123</t ...