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. Makefile,Shell command,Shell Language 之间的联系

    1. Makefile 首先要知道Makefile 是什么东西,Makefile 是一个指令文件,里面存储着自定义的命令(可以借助已有的命令创造而来)在不同的系统下对Makefile 的区别不一样,L ...

  2. UVA 674 Coin Change (完全背包)

    解法 dp表示目前的种数,要全部装满所以f[0]=1其余为0的初始化是必不可少的 代码 #include <bits/stdc++.h> using namespace std; int ...

  3. ndk编译libpcap 1.7.4

    android完全菜鸟,绝对的第一次接触,想做手机抓包,在网上搜又是NDK 又是JNI 又是JNETPCAP 完全蒙了,让我这种android和java都弄不明白什么关系的人情何以堪! 静下心想一想, ...

  4. codeforces 373 A - Efim and Strange Grade(算数模拟)

    codeforces 373 A - Efim and Strange Grade(算数模拟) 原题:Efim and Strange Grade 题意:给出一个n位的实型数,你可以选择t次在任意位进 ...

  5. Sliding Window(滑动窗口)

    Time Limit: 12000MS   Memory Limit: 65536K Total Submissions: 58002   Accepted: 16616 Case Time Limi ...

  6. CodeForces 370C

    这道题其实是挺简单的.首先很容易发现最多人用的颜色的人数如果大于n/2,就肯定不能让全部人都成功戴上两只不同颜色的手套.反过来想,如果这个人数小于等于n/2又如何呢?的确,这就能让全部人都能戴上两只不 ...

  7. Spring Framework体系结构简介

    说明:以下转自Spring官方文档,用的版本为4.3.11版本. 一.引用官方文档 2.2.1核心集装箱 所述核心容器由以下部分组成spring-core, spring-beans,spring-c ...

  8. nodejs fs.open

    fs.open(path, flags, [mode], [callback(err, fd)])是 POSIX open 函数的封装,与 C 语言标准库中的 fopen 函数类似.它接受两个必选参数 ...

  9. _deque实现

    /* deque是一种双向开口的连续线性空间,可以在头尾两端分别做元素的插入和删除操作 常用接口:back(), front(), push_back(), pop_back(), push_fron ...

  10. 【CV论文阅读】 Fast RCNN + SGD笔记

    Fast RCNN的结构: 先从这幅图解释FAST RCNN的结构.首先,FAST RCNN的输入是包含两部分,image以及region proposal(在论文中叫做region of inter ...