理论教育 读取Agent事务中的数据

读取Agent事务中的数据

时间:2023-11-24 理论教育 版权反馈
【摘要】:Akka中的Agent和Actor都是基于STM来处理事务的。使用send有如下方式:使用alter如如下的方式:接下来,将详细介绍Akka的Agent和Actor事务中数据的操作。从Agent事务中读取数据,不涉及对数据的更新,因此没有必要将共享变量包装到一个STM的引用中。读取Agent事务中的数据示例。图11-8读取Agent中的数据,验证临界区中的代码可能执行多次Agent事务中数据的更新和读取是有差别的,因为涉及到对数据状态的改变,接下来看看Agent事务中数据的更新。

读取Agent事务中的数据

Akka中的Agent和Actor都是基于STM来处理事务的。这里先简单介绍一下Akka中的Agent。顾名思义,Agent是代理的意思,使用代理模式实现。Akka中的Agent提供了一个独立于位置的异步的操作,所有对Agent的操作都是异步操作。要使用Akka Agent,需要在项目中添加Akka Agent模块,可以到http://mvnrepository.com/tags/maven搜索Akka Agent,找到对应版本的Akka Agent并下载Jar包,将下载的Jar添加到工程中;若你新建的项目是SBT项目,可以直接在SBT项目中的build.sbt中添加:libraryDependencies+="com.typesafe.akka"%"akka-agent_2.10"%"2.3.14",SBT工具将自动下载对应的Jar包。先来了解一下Agent中的一些基本的操作。

1)创建Agent。创建Agent很简单,首先需要引入一个隐式变量,Agent对象的apply方法要用到该隐式变量,然后需要引入Agent对应的包,Agent创建如下所示。

978-7-111-54169-1-Chapter11-23.jpg

2)读取Agent。读取Agent中的值有两种方法,第一种是直接使用agent.get方法,第二种是使用agent(),其实查看源代码可以知道,agent()会调用apply方法,apply方法中仍然是调用的get方法。

3)更新Agent更新Agent的值,可以使用send或者alter方法。

使用send有如下方式:

978-7-111-54169-1-Chapter11-24.jpg

使用alter如如下的方式:

978-7-111-54169-1-Chapter11-25.jpg(www.daowen.com)

接下来,将详细介绍Akka的Agent和Actor事务中数据的操作。

从Agent事务中读取数据,不涉及对数据的更新,因此没有必要将共享变量包装到一个STM的引用中。例11-7中,Demo类里面定义了run方法,run方法中使用yield关键字产生出20个座位并存放到seats中,在Future块中移除seats列表的前面10个元素,并调用Thread.sleep方法使线程睡眠50ms。定义一个变量nrRuns,用于记录临界区代码执行次数,在atomic中将检测冲突并触发临界区代码重新执行。通过此例展示Agent中数据的读取,并验证临界区中的代码在发生冲突的情况下将会执行多次。

【例11-7】读取Agent事务中的数据示例。

978-7-111-54169-1-Chapter11-26.jpg

例11-7中,在atomic块中首先通过seatsAgent.get得到当前的座位列表,然后Thread.sleep(100)使线程睡眠100 ms,最后通过seatsAgent.get.head获得可用座位列表的firstSeat。在Await.ready(future,Duration.create(1,TimeUnit.SECONDS))执行的时候,future线程先将可用座位减了10个。当atomic块中的睡眠100 ms之后,seatsAgent.get.head将会触发检查,发现seatsAgent状态已经改变,因此会重新执行临界区代码,nrRuns将会加1,临界区代码第二次执行检测到seatsAgent没有发生改变,因此直接结束执行atomic。所以程序结束后nrRuns一定是大于1的,firstSeats的座位编号也是10。执行结果如图11-8所示。

978-7-111-54169-1-Chapter11-27.jpg

图11-8 读取Agent中的数据,验证临界区中的代码可能执行多次

Agent事务中数据的更新和读取是有差别的,因为涉及到对数据状态的改变,接下来看看Agent事务中数据的更新。

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

我要反馈