使用GPars解决常见并发问题 - 编程入门网
rstWins(m1, m2)) {
winner = p2
} // else tie
if(p1.compareTo(p2) < 0) {
println toString(p1, m1) + ", " + toString(p2, m2) + ", winner = " + winner
} else {
println toString(p2, m2) + ", " + toString(p1, m1) + ", winner = " + winner
}
}
String toString(player, move) {
return player + " (" + move + ")"
}
boolean firstWins(Move m1, Move m2) {
return (m1 == Move.ROCK && m2 == Move.SCISSORS) ||
(m1 == Move.PAPER && m2 == Move.ROCK) ||
(m1 == Move.SCISSORS && m2 == Move.PAPER)
}
}
final def player1 = new Player(name: "Player 1")
final def player2 = new Player(name: "Player 2")
final def coordinator = new Coordinator(player1: player1, player2: player2, games: 10)
[player1,player2,coordinator]*.start()
coordinator << "start"
coordinator.join()
[player1,player2]*.terminate()
使用GPars解决常见并发问题(8)时间:2012-03-17 IBM Alex Miller清单 9 含有对 “Rock, Paper, Scissors” 游戏的完整表示,该游戏是通过 GPars 使用一个 Coordinatoractor 和两个 Playeractors 实现的。Coordinator发送一条 play消息给两个 Players,然后等待接收响应。在它接收到两条响应之后,Coordinator打印出比赛结果并自我发送一条消息,以开始新游戏。Playeractors 等待动向请求,因此每一个都用一个任意举动进行响应。 GPars 很好地实现了所有关键 actor 功能以及一些额外功能。actor 方法也许不是针对所有并发性问题的最佳解决方案,但是它确实提供了很好的方式来建模涉及消息传递的问题。 Agents Agents 在 Clojure中用于协调对可识别变更状态的多线程访问。Agents 分离不必要的身份(所指内容的名称)耦合和该身份引用的当前值。在大部分语言中,这两个方面有着千丝万缕的联系,因此拥有名称也就意味着您可以变更值。该关系如图 4 所示: 图 4. 管理状态的 Agent Agents 在变量持有者与可变状态本身之间提供一层间接关系。要更改状态,您可以向 agent 传递一个函数,然后 agent 评估功能流,用每个函数的输出替换状态。由于 agent 序列化了数据访问,因此不会有竞争条件或数据损坏风险。 此外,数据的读取包括查看当前快照,这仅需很少的并发性开销,因为快照不会改变。 变更被异步发送到 agents。如有必要,一个线程可以阻止 agent,直至其更改被应用,或者您可以在应用变更时指定执行一个操作。 GPars 中的 agents GPars 实现 Clojure 中的很多 agent 功能。在清单 10 中,我建模了一个僵尸进程入侵场景,并管理了 agent 内的世界状态。有两个线程:其中一个线程假设每隔一定时间,一个僵尸进程就会吃人脑,将该数字转化为僵尸。另一个进程假设其余僵尸进程的 5% 被幸存者使用弹枪杀死。主线程监守世界并报告入侵进度。 清单 10. 保护世界免受僵尸大灾难
|
凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢! |