いくつかの文字列を見た回数を追跡するためにScalaで可変マップを使用したいとします。シングルスレッドのコンテキストでは、これは簡単です:変更可能なマップの値をスレッドセーフに変換する
import scala.collection.mutable.{ Map => MMap }
class Counter {
val counts = MMap.empty[String, Int].withDefaultValue(0)
def add(s: String): Unit = counts(s) += 1
}
残念ながら、これはスレッドセーフを、get
とupdate
がアトミックに発生しませんので、ではありません。
import scala.concurrent.stm._
class Counter {
val counts = TMap.empty[String, Int]
def add(s: String): Unit = atomic { implicit txn =>
counts(s) = counts.get(s).getOrElse(0) + 1
}
}
:私は
ScalaSTMさんを使用することができます知っている
def replace(k: A, f: B => B): Option[B]
:
Concurrent maps次のようになり、私は必要なものを、変更可能なマップのAPIにa few atomic operationsを追加ではなく、
しかし、(今のところ)それはまだ余分な依存関係です。他のオプションには、アクター(別の依存関係)、同期(潜在的に効率の悪い)、Javaのatomic references(less idiomatic)などがあります。
一般的に私はScalaの可変マップを避けたいと思っていますが、時にはこの種のものが必要でした。最近では、私の指を横切るのではなく、ナイーブな解決策に噛まれている)。
私は(など明快対パフォーマンス、対余分な依存関係)のトレードオフの数がここにあります知っているが、Scalaの2.10で、この問題を「右」の答えのようなものはありますか?
:
テストは次のようになりますか? 'Counter.add'は単にそれにfire-and-forgetメッセージを送ります。読書に関しては、あなたの必要に応じて、同時に起こることも、俳優を通過することもできます。 – gourlaysama