akka与neety_Akka STM –与STM Ref和Agent一起打乒乓球
akka與neety
乒乓是一個(gè)經(jīng)典示例,其中2個(gè)玩家(或線程)訪問共享資源–乒乓表并在彼此之間傳遞Ball(狀態(tài)變量)。 使用任何共享資源,除非我們同步訪問,否則線程可能會(huì)遇到潛在的死鎖情況。PingPong算法非常簡(jiǎn)單
如果輪到我{
更新下一輪
ping / pong-記錄點(diǎn)擊
通知其他線程
}其他{
等待通知
}
讓我們來看一個(gè)例子,看看它是如何工作的! 這是我們的Player類,它實(shí)現(xiàn)Runnable并接受對(duì)共享資源和消息的訪問
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表類,該類具有一個(gè)同步方法hit(),無論是否輪到我,都將在其中進(jìn)行檢查。 如果輪到我了,請(qǐng)記錄ping并更新對(duì)手姓名的共享變量。
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) {}}}就是這樣,我們正在運(yùn)行PingPong游戲。 在這種情況下,我們看到了同步方法hit()如何僅允許一個(gè)線程訪問共享資源–其Turn。
Akka STM提供了兩個(gè)構(gòu)造Refs和Agents。 引用(事務(wù)引用)提供對(duì)多個(gè)身份的協(xié)調(diào)同步訪問。 代理提供對(duì)單個(gè)身份的非協(xié)調(diào)異步訪問。
參考
在我們的例子中,由于共享狀態(tài)變量是單個(gè)標(biāo)識(shí),因此引用的使用是過大的,但是我們?nèi)匀粫?huì)繼續(xù)查看它們的用法。
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) {}}}}這里的關(guān)鍵是以下
- 同步關(guān)鍵字丟失
- 將狀態(tài)變量定義為Ref
//對(duì)Ref.View的更新是同步的
Ref.View <string>其Turn; - 調(diào)用更新Ref是協(xié)調(diào)和同步的
whoTurn.set(opponent) ;
因此,當(dāng)我們使用Ref保持狀態(tài)時(shí),對(duì)Ref的訪問會(huì)在事務(wù)中自動(dòng)同步。
代理商
由于代理提供了不協(xié)調(diào)的異步訪問,因此使用代理進(jìn)行狀態(tài)操縱將意味著我們需要等到所有更新都已應(yīng)用到代理之后。 代理為獲取提供非阻塞訪問。
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.}}這里的關(guān)鍵是以下
- 同步關(guān)鍵字丟失
- 將狀態(tài)變量定義為Agent
//對(duì)Ref.View的更新是同步的
Agent <string>其Turnn; - 等待對(duì)代理的更新,因?yàn)閷?duì)代理的更新是異步的
字符串結(jié)果= whoTurn.await(new Timeout(5,SECONDS)); - 調(diào)用更新Ref是協(xié)調(diào)和同步的
whoTurn.send(opponent) ;
這些示例中引用的所有代碼都可以在– https://github.com/write2munish/Akka-Essentials/tree/master/AkkaSTMExample/src/main/java/org/akka/essentials/stm/pingpong中找到
示例1 –用于基于普通線程的同步
示例2 –使用Refs進(jìn)行同步 示例3 –使用代理進(jìn)行同步
參考:在Akka Essentials博客上,與我們的JCG合作伙伴 Munish K Gupta 一起使用STM玩 -Refs 和Agents 。
翻譯自: https://www.javacodegeeks.com/2012/05/akka-stm-playing-pingpong-with-stm-refs.html
akka與neety
總結(jié)
以上是生活随笔為你收集整理的akka与neety_Akka STM –与STM Ref和Agent一起打乒乓球的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ddos攻击下载(ddos攻击中文版)
- 下一篇: 汽车改包围车管所备案流程(汽车改包围车管