並行性は、複数の問題と落とし穴を伴う広大な領域です。すべての問題を解決できる単一のアプローチはありません。真の並行処理の専門家は、複数の方法を組み合わせて最良の結果を得ることができます。
現在、JVM の世界では、特に競合が非常に激しい場合、カウンターをインクリメントするためのアトミック整数よりも優れた代替手段はないと思います。
そうは言っても、アクターを使用する場合、パフォーマンスとスケーラビリティーを得るための秘訣は、ask ( ?
) 操作をできるだけ避けることです。代わりにtell ( ) を使用して!
から、yield を使用します。結果が利用可能になると、アクターはそれを受け取り、制御を再開します。何もブロックされず、その間、スレッド プールは他のアクターを処理できます。これは、ほとんどのコードがアクター内にある場合にのみ機能します。
Thomas ソリューションから始めて、次のように記述できます。
case object Inc
case class Count(i)
class IncrementingActor extends Actor {
var i = 0
protected def receive = {
case Inc =>
i += 1
sender ! Count(i)
}
}
class FooActor( counter: ActorRef ) extends Actor {
protected def receive = {
case DoSomething() => {
// Perform some work
counter ! Inc
}
case Count(i) => {
// Do something with the counter result
}
}
}