Akka学习笔记07--TypedActor(有类型的Actor)

Akka 中的有类型 Actor 是 Active Objects 模式的一种实现,将异步的调用执行逻辑封装在一个方法内,在代码层面保证了的顺序执行思维。

Active Objects 设计模式

来自维基百科 Active Objects 。

该设计模式包含了六种元素:

  • 代理:提供了面向客户端的带有公开方法的接口。
  • 接口:定义了到 active object 的请求方法(业务代码提供)。
  • 来自客户端的一序列等待请求。
  • 调度器:决定接下来执行哪个请求。
  • active object 方法的实现类(业务代码提供)。
  • 一个回调或变量,用以让客户端接收结果。

上述六个元素中,除了标记(业务代码提供)的,其余都是由该模式的实现提供的,在本篇也就是 Akka。

Akka 是通过 JDK 的 java.lang.reflect.Proxy 来自实现 active object 模式的。

使用 TypedActor

TypedActor 将消息传递隐藏在方法调用内,但它也必须满足 Actor 顺序地、独占地执行 Actor 代码逻辑的要求。

有类型Actor相对于普通Actor的优势在于有类型Actor拥有静态的契约,你不需要定义你自己的消息,它的劣势在于对你能做什么和不能做什么进行了一些限制,i.e. 你不能使用 become/unbecome。

1. 定义业务接口和实现

  1. <pre name="code" class="ruby">import scala.concurrent.Future  
  2.   
  3. /**  
  4.  * Created by Administrator on 15-2-25.  
  5.  */  
  6. trait Square {  
  7.   //长宽各增加1  
  8.   def add(x: Int, y: Int):Unit  
  9.   
  10.   // 面积  
  11.   def area: Future[Int]  
  12. }  
  13.   
  14. class CalculateSquare(var length: Int, var width: Int) extends Square {  
  15.   
  16.   def add(x: Int, y: Int):Unit = {  
  17.     this.length += 1  
  18.     this.width += 1  
  19.   }  
  20.   
  21.   def area: Future[Int] = {  
  22.     println("wait before area")  
  23.     Thread.sleep(2000)  
  24.     Future.successful(length * width)  
  25.   }  
  26.   
  27. }  
 

2. 封装成 active object 非常简单

val square = TypedActor(system).typedActorOf(TypedProps(classOf[Square],newSquareImpl(10,20)),"name")

3. 测试 TypedActor 的执行效果

  1. <pre name="code" class="ruby">import akka.actor._  
  2. import scala.concurrent.duration._  
  3. import scala.concurrent.Await  
  4.   
  5. /**  
  6.  * Created by Administrator on 15-2-25.  
  7.  */  
  8.   
  9. object LearnTypedActor {  
  10.   def main(vars: Array[String]) {  
  11.     val system = ActorSystem("myActorSystem")  
  12.   
  13.     val calculator:Square = TypedActor(system).typedActorOf(TypedProps(classOf[Square], new CalculateSquare(10, 20)))  
  14.     //Send and receive,类似ask  
  15.     val future01 = calculator.area  
  16.     val result01 = Await.result(future01, 5 second)  
  17.     println(result01)  
  18.   
  19.     //Fire and forget, 类似tell  
  20.     calculator.add(1,2)  
  21.   
  22.     val future02 = calculator.area  
  23.     val result02 = Await.result(future02, 5 second)  
  24.     println(result02)  
  25.   
  26.     system.shutdown()  
  27.   }  
  28. }  
 

这里定义了一个 SenderActor 是为了并发地调用 TypedActor 实现的方法。由于 area 方法的实现里进行了等待,circumference 没有,如果 TypedActor 不是顺序地处理消息,那么circumference 应该比area 先执行,否则是后执行。

4. 结果

  1. <pre name="code" class="ruby">wait before area  
  2. 200  
  3. wait before area  
  4. 231  
 

结果是符合预期的,先调用的 area 方法虽然进行了等待,但后调用的circumference 还是得等area 方法执行完后才能执行。

TypedActor 的优势

如果我们通过消息传递的方式来调用,就需要编写代码的人具有异步的思维,异步地思考,而人的思维模式都是顺序地思考的,这就需要很大的转变。

TypedActor 保持了消息传递的优点,且 Akka 框架屏蔽了异步性,允许程序员继续用顺序的思维思考问题。

另一个优势就是它是有类型的,由于消息传递被封装在方法调用内,所以传递的消息都有了类型安全的保障,直接使用 Actor,可能会收到任意类型的消息。


Tips:转载于http://coderbee.net/index.php/akka/20140825/1031

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值