理论教育 Scala开发实战:探究不同类型的Actor

Scala开发实战:探究不同类型的Actor

时间:2023-11-24 理论教育 版权反馈
【摘要】:在10.2一节中重点介绍了普通Actor,因此在本节中不再赘述,本节将重点放在有类型Actor上。有类型Actor是Active Object模式的一种实现。图10-10代理模型1)运行时,Client调用Proxy对象并执行方法。Scheduler或Invocation Handler将会拦截请求。在创建第一个有类型的Actor之前,先来了解一下手上可供使用的工具,它位于akka.actor.TypedActor中。例10-15将通过一个例子来实际使用TypedActor。Akka中的有类型Actor,将异步的调用和执行封装在方法中,在代码层面保证了的顺序执行思维。

Scala开发实战:探究不同类型的Actor

Akka中的Actor分为有类型Actor和普通Actor。Akka中的有类型Actor是Active Objects模式的一种实现。Smalltalk诞生之时,就已经默认地将方法调用从同步操作改为异步派发。

有类型Actor由两部分组成:一个公开的接口和一个实现,“企业级”Java开发者对此应该非常熟悉。对普通Actor来说,拥有一个外部API(公开接口的实例)来将方法调用异步地委托给其实现的私有实例。

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

有类型Actor是使用JDK Proxies实现的,JDK Proxies提供了非常简单的API来拦截方法调用。在10.2一节中重点介绍了普通Actor,因此在本节中不再赘述,本节将重点放在有类型Actor上。

有类型Actor是Active Object模式的一种实现。Active Object这种模式的主要思想是将方法的调用和执行分离,使Actor的实现更清晰、更简洁。在这种设计模式中,为了将方法的执行从方法的调用中分离,必须将方法的执行和方法的调用放置到隔离的线程中去,有了调用和执行相互隔离的线程,在Actor实现的时候,就可以并行、异步地获取对象状态。

怎样分离方法的调用和方法的执行呢?Active Object模式为了实现这一点,使用了代理模式,将接口和实现进行分离,思想就是在相互隔离的线程中分别运行代理和实现。原理如图10-10所示。

978-7-111-54169-1-Chapter10-36.jpg

图10-10 代理模型

1)运行时,Client调用Proxy对象并执行方法。

2)Proxy将方法调用转换成成对的Schedular或者Invocation Handler的请求。Scheduler或Invocation Handler将会拦截请求。

3)Scheduler或者Invacation Handler将方法请求放入队列。

4)监控队列,执行可执行的方法。

5)Scheduler或者Invocation Handler分发请求到具体实现方法的对象上执行。

6)具体对象执行方法,给Client端返回Future结果。

在了解Typed Actor实现的基本思想之后,下面将创建Typed Actor。

在创建第一个有类型的Actor之前,先来了解一下手上可供使用的工具,它位于akka.actor.TypedActor中。这些可用的工具方法如下所示。

978-7-111-54169-1-Chapter10-37.jpg

978-7-111-54169-1-Chapter10-38.jpg

要创建有类型Actor需要一个或多个接口,以及一个实现。创建有类型Actor最简单的方法是:val myTypedActor:Trait=TypedActor(system).typedActorOf(TypedProps[Impl]())。例10-15将通过一个例子来实际使用TypedActor。在实现Typed Actor之前,关于接口方法有几点需要说明:

1)如果方法返回void类型,该方法调用如有类型Actor中的tell一样,属于“fire and forget”类型。(www.daowen.com)

2)如果方法返回Option类型,该方法将会一直阻塞,直到结果的返回,如果在设置的超时时间内还没有返回,方法将停止并返回“None”。

3)如果方法返回Future类型,该方法调用跟有类型Actor中的ask一样,不会阻塞,会立即返回一个Future。

4)方法返回其他类型,该方法将会一直阻塞,直到结果返回,一直到超时。

接下来将通过一个实际的例子,展示TypedActor的使用,在例10-10中定义了一个Cal接口,该接口中有add、multi两个抽象方法,分别用于求和与求积。Calculate继承Cal接口并实现add、multi两个抽象方法。在LearnTypedActor对象中,使用TypedActor的typedAc⁃torOf工厂方法,实例化出Calculate对象,调用Calculate对象的add和multi方法,打印出返回值。完整代码如下所示。

【例10-11】实际使用TypedActor示例。

978-7-111-54169-1-Chapter10-39.jpg

978-7-111-54169-1-Chapter10-40.jpg

输出结果如图10-11所示。

978-7-111-54169-1-Chapter10-41.jpg

图10-11 使用TypedActor

在上述例子中,定义了一个Cal的Trait,Calculate实现Cal这个Trait,在main方法中通过val calculator:Cal=TypedActor(system).typedActorOf(TypedProps(classOf[Cal],new Calculate(10,20)))产生的TypedActor,通过调用calculator实例上的add和multi方法来测试。TypedActorOf方法的调用,返回一个Calculate动态代理实例。

Akka中的有类型Actor,将异步的调用和执行封装在方法中,在代码层面保证了的顺序执行思维。Active Objects设计模式包含6种元素:

1)代理:提供了面向客户端的带有公开方法的接口。

2)接口:定义了到active object的请求方法(业务代码提供)。

3)来自客户端的序列等待请求。

4)调度器:决定接下来执行哪个请求。

5)active object方法的实现类(业务代码提供)。

6)一个回调或变量,以让客户端接收结果。

免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。

我要反馈