快速业务通道

使用GPars解决常见并发问题 - 编程入门网

作者 佚名技术 来源 NET编程 浏览 发布时间 2012-06-13
们创建降低复杂度的更高的抽象级别。

我将要展示的三种方法是 actors、agents 和数据流变量,它们均受 GPars 支持。

Actors

actor 范例最初是在 Erlang 中普及的,而最近因在 Scala 中的使用而声名远扬。Erlang 是于 20 世纪 80 年代和 90 年代在 Ericsson 专为 AXD301 电信交换机而设计的。设计这种交换机很有挑战性,需要考虑几个因素:高可靠性、无停机时间(热代码升级)、大规模并发性。

Erlang 以 “进程” 为前提,如同轻量级线程(而不像操作系统进程),但是不直接映射到本地线程。进程的执行由底层虚拟机调度。Erlang 中的进程内存较小,可快速启动和进行上下文切换。

Erlang actors 仅仅是在进程上执行的函数。Erlang 无共享内存,且其中的所有状态都是不变的。不可变数据是许多侧重于并发性的语言的关键方面,因为它有如此好的属性。不可变数据是不能更改的,因此读取不可变数据无需用到锁,即使有多个线程读取时也是如此。对不可变数据的更改包括构建数据新版本并从新版本开始工作。对于主要在共享可变状态语言(比如 Java 语言)方面有背景知识的开发人员来说,这一角度转变需要一些时间来适应。

状态是通过传递不可变消息在 actors 之间 “共享” 的。每个 actor 都有一个邮箱,而且通过在其邮箱中接收消息可反复执行 actor函数。消息的发送通常是异步的,尽管构建同步调用也很简单,而且有些 actor 实现提供这样的特性。

GPars 中的 Actors

GPars 使用来自 Erlang 和 Scala 的许多概念实现 actor 模型。GPars 中的 Actors 是从邮箱中使用消息的轻量级进程。根据消息是由 receive()或 react()方法使用,可以放弃或保留线程绑定。

在 GPars 中,可以利用接受闭包的 factory 方法或通过为 groovyx.gpars.actor.AbstractPooledActor划分子类来创建 actors。在 actor 中,应当由一个 act()方法。通常 act()方法包含一个无止境重复的循环,然后调用 react(面向轻量级 actor)或 receive(面向仍然与其线程绑定的重量级 actor)。

清单 9. ''Rock, Paper, Scissors'' (rps.groovy) 的 actor 实现

package puredanger.gparsdemo.rps;   import groovyx.gpars.actor.AbstractPooledActor   enum Move { ROCK, PAPER, SCISSORS }   @Grab(group=''org.codehaus.gpars'', module=''gpars'', version=''0.10'')   class Player extends AbstractPooledActor {   String name   def random = new Random()   void act() {    loop {     react {      // player replies with a random move      reply Move.values()[random.nextInt(Move.values().length)] } } } }   class Coordinator extends AbstractPooledActor {   Player player1    Player player2   int games   void act() {    loop {     react {   // start the game      player1.send("play")      player2.send("play")      // decide the winner      react {msg1 ->       react {msg2 ->        announce(msg1.sender.name, msg1, msg2.sender.name, msg2)        // continue playing         if(games-- > 0)         send("start")        else         stop() } } } } }   void announce(p1, m1, p2, m2) {    String winner = "tie"    if(firstWins(m1, m2) && ! firstWins(m2, m1)) {     winner = p1     } else if(firstWins(m2, m1) && ! fi

凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

分享到: 更多

Copyright ©1999-2011 厦门凌众科技有限公司 厦门优通互联科技开发有限公司 All rights reserved

地址(ADD):厦门软件园二期望海路63号701E(东南融通旁) 邮编(ZIP):361008

电话:0592-5908028 传真:0592-5908039 咨询信箱:web@lingzhong.cn 咨询OICQ:173723134

《中华人民共和国增值电信业务经营许可证》闽B2-20100024  ICP备案:闽ICP备05037997号