乒乓是一个经典示例,其中2个玩家(或线程)访问共享资源–乒乓球桌并在彼此之间传递Ball(状态变量)。 使用任何共享资源,除非我们同步访问,否则线程可能会遇到潜在的死锁情况。

PingPong算法非常简单

如果轮到我{
更新下一轮
ping / pong-记录点击
通知其他线程
}其他{
等待通知
}

让我们来看一个例子,看看它是如何工作的! 这是我们的Player类,它实现Runnable并接受对共享资源和消息的访问

public class Player implements Runnable {PingPong myTable;  Table where they playString myOpponent;public Player(String opponent, PingPong table) {myTable = table;myOpponent = opponent;}public void run() {while (myTable.hit(myOpponent));}}

其次,我们看到PingPong表类,该类具有一个同步方法hit(),无论是否轮到我,都在其中进行检查。 如果轮到我了,请记录ping并更新对手姓名的共享变量。

public class PingPong {state variable identifying whose turn it is.private String whoseTurn = null;public synchronized boolean hit(String opponent) {String x = Thread.currentThread().getName();if (x.compareTo(whoseTurn) == 0) {System.out.println('PING! (' + x + ')');whoseTurn = opponent;notifyAll();} else {try {  wait(2500); } catch (InterruptedException e) { }}}}

接下来,我们开始游戏并使玩家开始!

public class Game {public static void main(String args[]) {PingPong table = new PingPong();Thread alice = new Thread(new Player('bob', table));Thread bob = new Thread(new Player('alice', table));alice.setName('alice');bob.setName('bob');alice.start();  alice starts playingbob.start();  bob starts playingtry {Wait 5 secondsThread.sleep(5000);} catch (InterruptedException e) {}table.hit('DONE');  cause the players to quit their threads.try {Thread.sleep(100);} catch (InterruptedException e) {}}}

就是这样,我们正在运行PingPong游戏。 在这种情况下,我们看到了同步方法hit()如何仅允许一个线程访问共享资源– itsTurn。

Akka STM提供了两个构造Refs和Agents。 引用(事务引用)提供对多个身份的协调同步访问。 代理提供对单个身份的非协调异步访问。

参考

在我们的例子中,由于共享状态变量是单个标识,因此引用的使用是过大的,但是我们仍然会继续查看它们的用法。

public class PingPong {updates to Ref.View are synchronousRef.View<String> whoseTurn;public PingPong(Ref.View<String> player) {whoseTurn = player;}public boolean hit(final String opponent) {final String x = Thread.currentThread().getName();if (x.compareTo(whoseTurn.get()) == 0) {System.out.println('PING! (' + x + ')');whoseTurn.set(opponent);} else {try {wait(2500);} catch (Exception e) {}}}}

这里的关键是以下

  • 同步关键字丢失
  • 将状态变量定义为Ref
    //更新到Ref.View是同步的
    Ref.View <string>其Turn;
  • 调用更新Ref是协调和同步的
    whoTurn.set(opponent) ;

因此,当我们使用Ref保持状态时,对Ref的访问会在事务中自动同步。

代理商

由于代理提供了不协调的异步访问,因此使用代理进行状态操作将意味着我们需要等到所有更新都已应用到代理之后。 代理为获取提供非阻塞访问。

public class PingPong {Agent<String> whoseTurn;public PingPong(Agent<String> player) {whoseTurn = player;}public boolean hit(final String opponent) {final String x = Thread.currentThread().getName();wait till all the messages are processed to make you get the correct value, as updated to Agents areasyncString result = whoseTurn.await(new Timeout(5, SECONDS));if (x.compareTo(result) == 0) {System.out.println('PING! (' + x + ')');whoseTurn.send(opponent);} else {try {wait(2500);} catch (Exception e) {}}return true;  keep playing.}}

这里的关键是以下

  • 同步关键字丢失
  • 将状态变量定义为Agent
    //更新到Ref.View是同步的
    Agent <string>其Turnn;
  • 等待对代理的更新,因为对代理的更新是异步的
    字符串结果= whoTurn.await(new Timeout(5,SECONDS));
  • 调用更新Ref是协调和同步的
    whoTurn.send(opponent) ;

这些示例中引用的所有代码都可以在– https://github.com/write2munish/Akka-Essentials/tree/master/AkkaSTMExample/src/main/java/org/akka/essentials/stm/pingpong中找到
示例1 –用于基于普通线程的同步
示例2 –使用Refs进行同步 示例3 –使用代理进行同步

参考:在Akka Essentials博客上,与我们的JCG合作伙伴 Munish K Gupta 一起使用STM – Refs和Agents打乒乓球。

翻译自: https://www.javacodegeeks.com/2012/05/akka-stm-playing-pingpong-with-stm-refs.html

Akka STM –与STM Ref和Agent进行乒乓球比赛相关推荐

  1. akka与neety_Akka STM –与STM Ref和Agent一起打乒乓球

    akka与neety 乒乓是一个经典示例,其中2个玩家(或线程)访问共享资源–乒乓表并在彼此之间传递Ball(状态变量). 使用任何共享资源,除非我们同步访问,否则线程可能会遇到潜在的死锁情况. Pi ...

  2. Clojure的并发(一) Ref和STM

    Clojure 的并发(一) Ref和STM Clojure 的并发(二)Write Skew分析 Clojure 的并发(三)Atom.缓存和性能 Clojure 的并发(四)Agent深入分析和A ...

  3. 寄存器内存读写指令(二) —— 多寄存器读写 LDM / STM

    有的时候,CPU可能会遇到 a++; b++; c++,这个时候为了提升效率,CPU可能会一次将多个寄存器里的变量保存到内存中.这个时候之前介绍的 LDR / STR 指令虽然也能实现,但只能操作一个 ...

  4. 4、英飞凌-AURIX-TC3X7:系统定时器-STM实验

    4.英飞凌 AURIX TC3X7 系统定时器-STM实验 目录 4.英飞凌 AURIX TC3X7 系统定时器-STM实验 1.STM简介 1.1.作用 1.2.特征 1.3.STM模块框图 2.实 ...

  5. Y分钟学clojure

    Clojure是运行在JVM上的Lisp家族中的一员.她比Common Lisp更强调纯函数式编程,且自发布时便包含了一组工具来处理状态. 这种组合让她能十分简单且自动地处理并发问题. (你需要使用C ...

  6. Clojure入门教程: Clojure – Functional Programming for the JVM中文版

    http://xumingming.sinaapp.com/302/clojure-functional-programming-for-the-jvm-clojure-tutorial/ api:h ...

  7. colojure语言基础入门

    作者:xumingming| 可以转载, 但必须以超链接形式标明文章原始出处和作者信息及版权声明 网址: http://xumingming.sinaapp.com/302/clojure-funct ...

  8. Clojure – Functional Programming for the JVM中文版

    Clojure – Functional Programming for the JVM中文版 发表于 2011 年 12 月 07 日 由xumingming 作者: xumingming | 可以 ...

  9. Clojure入门教程

    Clojure入门教程: Clojure – Functional Programming for the JVM中文版 发表于 2011 年 12 月 07 日 由 xumingming 作者: x ...

最新文章

  1. 结构体内指针数组调用_指针的这些技巧你都掌握了吗
  2. weblogic.jdbc.wrapper.Blob_oracle_sql_BLOB cannot be cast to oracle.sql.BLOB 解决方法
  3. eclipse写java实现端口_使用eclipse(windows)在java中使用IPv6地址和端口号创建套接字...
  4. 第二章:2.1 微分方程、差分方程求解(举例)
  5. phpcms URL修改
  6. 汽车产业云上多地域高可用消息系统构建
  7. COCO 54.7mAP!DetectoRS目标检测:改进主干网,成就新高度!
  8. 面向对象--闭包 继承
  9. js微信抢红包脚本代码_如何利用JavaScript来实现微信抢红包功能的示例代码
  10. Spring发送基于freemarker模板的邮件
  11. 用40年前的电脑打开女神图片,这你敢信?
  12. 知识竞赛时,倒计时字体的大小和位置如何调整?
  13. Python小白的飞桨之旅
  14. 格美净水器:家用净水器必看的6点
  15. SAP中公司间过账问题处理实例
  16. 随身WIFI刷真Linux(Debian)系统搭配拓展坞做超低功耗服务器
  17. 人生需要认真思考的一些故事
  18. 学生HTML个人网页作业作品 HTML+CSS校园环保(大学生环保网页设计与实现)
  19. C++鲜为人知的符号
  20. 程序员经验分享:34岁安卓开发大叔感慨,好文推荐

热门文章

  1. java转换文本文件到xlsx(自制缓冲区,无需先验文件行数)
  2. log4j2 logger_简单一致的Log4j2 Logger命名
  3. 子模板继承父模板示例_模板设计模式示例
  4. 红帽 jboss_红帽正式宣布发布JBoss BPM Suite 6和JBoss BRMS 6
  5. lucene 多个分词查找_使用Lucene的新FreeTextSuggester查找长尾建议
  6. 异步重试_异步重试模式
  7. JArchitect v2017发布!
  8. NetBeans Java EE技巧7:忽略的Java类和XHTML编辑器快捷方式
  9. 本机速度文件支持的“纯” Java大数据存储
  10. 带有骆驼,ActiveMQ,Elasticsearch的HL7关键用例