What is STM? STM stands for Software Transactional Memory
Configure project Using sbt (Scala Build Tool)
libraryDependencies += ("org.scala-stm" %% "scala-stm" % "0.7")
Add dependency to pom.xml (for Scala 2.10)
<dependencies>
<dependency>
<groupId>org.scala-stm</groupId>
<artifactId>scala-stm_2.10</artifactId>
<version>0.7</version>
</dependency>
</dependencies>
Prerequisites Required imports
import scala.concurrent.stm._Useful classes and methods
Ref, atomic, repeat
A Ref A Ref wraps a value and makes it transactional. Once value is wrapped, it's impossible to get or set the value outside of transcation
val userCount = Ref(42)Following attempt to call Ref.set() will not compile
userCount.get() //will not compileOutput
Exception:CompilerException: Compiler exception error: line 5: not enough arguments for method get: (implicit txn: scala.concurrent.stm.InTxn)Int. Unspecified value parameter txn. userCount.get() //will not compile ^
the same with Ref.set() method
userCount.set() //will not compileOutput
Exception:CompilerException: Compiler exception error: line 5: not enough arguments for method set: (v: Int)(implicit txn: scala.concurrent.stm.InTxn)Unit. Unspecified value parameter v. userCount.set() //will not compile ^
Compiler says that both methods have implicit parameter called txn. It represents current transaction. The only way to access value from ref is to call get/set method in transaction
Atomic - All or nothing ScalaSTM allows you to make block of code atomic. That means from the rest of code you cannot see any partial change in this block. atomic block is marked by word "atomic"
Common template to make block of code atomic
val result = atomic { implicit tx => /*your code here*/ }
val x1 = atomic { userCount.get(_) } //() (result)
val x2 = atomic { implicit tx => userCount.get } //() (result)
Accessing value out of atomic Following method will create transaction only for the duration of the call
userCount.single() //this will work //42 (result)and is equivalent to
atomic { userCount.get(_) } //42 (result)
Short forms of Ref.get/Ref.set Ref.set
atomic { implicit tx => userCount.set(56) } //() (result)
has shorter form
atomic { implicit tx => userCount() = 56 } //() (result)
Ref.get
atomic { implicit tx => val x = userCount.get; x } //42 (result)
has shorter form
atomic { implicit tx => val x = userCount(); x } //42 (result)
Example
atomic { implicit tx => "Hello world!" }OutputHello world!
No comments:
Post a Comment