Multithreading – what is Scala’s equivalent to clojure’s atom?
•
Java
Clojure has an Atom for changing state between threads in a synchronous and independent manner,that is not part of the STM. You use it like this:
user=> (def my-atom (atom 0)) #'user/my-atom user=> @my-atom 0 user=> (swap! my-atom inc) 1 user=> @my-atom 1 user=> (swap! my-atom (fn [n] (* (+ n n) 2))) 4
My question is: what is Scala's atom equivalent to clojure?
Solution
As @ shepmaster and @ om NOM NOM said, it is Java util. concurrent. atomic. Atomic encapsulation
An equivalent wrapper may be as follows:
import java.util.concurrent.atomic._
import scala.annotation.tailrec
object Atom {
def apply[A](init: A): Atom[A] = new Impl(new AtomicReference(init))
private class Impl[A](state: AtomicReference[A]) extends Atom[A] {
def apply(): A = state.get()
def update(value: A): Unit = state.set(value)
def transformAndGet(f: A => A): A = transformImpl(f)
@tailrec private final def transformImpl(fun: A => A): A = {
val v = state.get()
val newv = fun(v)
if (state.compareAndSet(v,newv)) newv
else transformImpl(fun)
}
}
}
trait Atom[A] {
def apply(): A
def update(value: A): Unit
def transformAndGet(f: A => A): A
}
For example:
val myAtom = Atom(0) myAtom() // --> 0 myAtom.transformAndGet(_ + 1) // --> 1 myAtom() // --> 1 myAtom.transformAndGet(_ * 4) // --> 4
If Scala STM is used, this function is built into the STM reference Single view:
scala> import scala.concurrent.stm._
import scala.concurrent.stm._
scala> val myAtom = Ref(0).single
myAtom: scala.concurrent.stm.Ref.View[Int] =
scala.concurrent.stm.ccstm.CCSTMRefs$IntRef@52f463b0
scala> myAtom()
res0: Int = 0
scala> myAtom.transformAndGet(_ + 1)
res1: Int = 1
scala> myAtom()
res2: Int = 1
scala> myAtom.transformAndGet(_ * 4)
res3: Int = 4
The advantage is that ref.apply has provided you with a dedicated cell of the original type, such as int instead of anyref (@r_48)_ 2419@ed ).
The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
二维码
