如何在 Actor 物件中使用可變 Map 來根據訊息存盤值?我的代碼
object TestActor {
final case class Command()
private val mmap: mutable.Map[Int,Map[Int,Int]] = mutable.Map[Int,Map[Int,Int]]()
def apply(): Behavior[Command] = Behaviors.receive {
case (context, Command()) =>
mmap = (1 -> (2 -> 3))
context.log.info(nmap)
}
}
這會導致問題,因為mmap它是靜態的,因為它是 scala 物件中的一個欄位。所以當多個執行緒給map添加一些值時,會產生奇怪的值。由于我仍然需要使用型別化的 akka 演員,有沒有辦法在物件中(或以其他方式)有一個欄位,以使我仍然可以使用物件來表示正在使用的演員akka.typed并且仍然有欄位不是TestActor演員之間共享?
uj5u.com熱心網友回復:
在 Akka Typed 的函式式 API(本示例使用)中,執行此操作的典型方法如下:
object TestActor {
final case class Command()
def apply(): Behavior[Command] =
fromMap(mutable.Map.empty)
private def fromMap(mmap: mutable.Map[Int, Map[Int, Int]]): Behavior[Command] =
Behaviors.receive {
case (context, Command()) =>
mmap = (1 -> Map(2 -> 3))
context.log.info(mmap)
Behaviors.same
}
}
在這里,object它基本上只是一個模塊,并且該物件的欄位最好被認為是全域變數。
請注意,還有一個面向物件的 API 用于定義型別化的 Actor,在 Scala 中它是:
object TestActor {
final case class Command()
def apply(): Behavior[TestActor.Command] =
Behaviors.setup { context =>
new TestActor(context)
}
}
class TestActor(context: ActorContext[TestActor.Command]) extends AbstractBehavior[TestActor.Command](context) {
val mmap: mutable.Map[Int, Map[Int, Int]] = mutable.Map.empty
def onMessage(msg: TestActor.Command): Behavior[TestActor.Command] = {
mmap = (1 -> Map(2, 3))
context.log.info(mmap)
this
}
}
值得注意的是,在 Akka 中,擁有vars 個不可變資料(即持有不可變值的可變容器)通常比擁有 sval個可變資料(即持有可變值的不可變容器)更好,因為這可以為參與者之外的某些東西暴露一個通道 (包括另一位演員)“從演員下面拉出地毯”。
在函式式 API 中,這通常采用如下形式:
object TestActor {
final case class Command()
def apply(): Behavior[Command] =
fromMap(Map.empty)
private def fromMap(map: Map[Int, Map[Int, Int]]): Behavior[Command] =
Behaviors.receive {
case (context, Command()) =>
val nextMap = map (1 -> Map(2 -> 3))
context.log.info(nextMap)
withMap(nextMap)
}
}
在 OO Scala API 中:
// TestActor companion object is as before
class TestActor(context: ActorContext[TestActor.Command]) extends AbstractBehavior[TestActor.Command](context) {
var map: Map[Int, Map[Int, Int]] = Map.empty
def onMessage(msg: TestActor.Command): Behavior[TestActor.Command] = {
map = map (1 -> Map(2 -> 3))
context.log.info(map)
this
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/444249.html
