Clojure 有一个原子 http://clojure.org/atoms for 以同步且独立的方式改变线程之间的状态 http://clojure.org/concurrent_programming, 这不是 STM 的一部分 https://stackoverflow.com/a/18976545/15441. You 像这样使用它 http://clojuredocs.org/clojure_core/clojure.core/atom:
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
我的问题是:Clojure 的 Atom 在 Scala 中相当于什么?
正如 @Shepmaster 和 @om-nom-nom 所说,它是一个包装器java.util.concurrent.atomic.Atomic...
.
等效的包装器可能如下所示:
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
}
Ex:
val myAtom = Atom(0)
myAtom() // --> 0
myAtom.transformAndGet(_ + 1) // --> 1
myAtom() // --> 1
myAtom.transformAndGet(_ * 4) // --> 4
如果你使用Scala-STM http://nbronson.github.io/scala-stm/,该功能内置于 STM 参考中,通过使用.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
优点是Ref.apply
已经为您提供了原始类型的专用单元格,例如Int
代替AnyRef
(盒装)。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)