Multithreading 什么是Scala与Clojure';s原子?

Multithreading 什么是Scala与Clojure';s原子?,multithreading,scala,concurrency,clojure,Multithreading,Scala,Concurrency,Clojure,Clojure for。你: 我的问题是:什么是Scala与Clojure的Atom的等价物?它不是Scala特有的,但我会在Java领域首先提到它。您想要/需要多少atom的功能?正如@Shepmaster和@om nom nom所说,它是java.util.concurrent.atomic.atomic…的包装器 等效的包装可以如下所示: import java.util.concurrent.atomic._ import scala.annotation.tailrec object

Clojure for。你:


我的问题是:什么是Scala与Clojure的Atom的等价物?

它不是Scala特有的,但我会在Java领域首先提到它。您想要/需要多少atom的功能?

正如@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
}
例:


如果使用,则该功能将通过使用
.single
视图内置到STM引用中:

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
(已装箱)。

顺便说一句,这里有一个与Clojure功能相匹配的Scala实现,包括监视支持:
val myAtom = Atom(0)
myAtom()  // --> 0
myAtom.transformAndGet(_ + 1) // --> 1
myAtom()  // --> 1
myAtom.transformAndGet(_ * 4) // --> 4
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