akka Actor中的可变集合返回NullPointerException

问题描述 投票:0回答:1

我有一个演员,每次调用websocket时都会调用websocket并更新地图。演员在命令的另一点使用相同的地图。

class MyActor(broker: InMemoryBroker) extends Actor {
val myMap: TrieMap[String, String] = new TrieMap[String, String]()

//Gets a response every 1 second 
webSocket.get(onReponse= r=> myMap(r.key) = r.value)


def receive()={
 case MyCommand(key)=>
   if(myMap.get(key).isDefined){     //Null pointer exception is thrown here
       //Do stuff
   }
}

我期望TrieMap是线程安全的,并且没有此类问题。有什么建议吗?

scala collections akka actor mutable
1个回答
2
投票

您应该在receive方法中进行尽可能多的处理。因此,与其直接在onResponse中更新地图,不如给自己发送消息并在收到地图时更新地图:

class MyActor(broker: InMemoryBroker) extends Actor {
  val myMap: TrieMap[String, String] = new TrieMap[String, String]()

  private case class UpdateMap(r: ???)

  //Gets a response every 1 second 
  webSocket.get(onReponse = r => self ! UpdateMap(r))

  def receive() = {
    case UpdateMap(r) =>
      myMap(r.key) = r.value

    case MyCommand(key) =>
      if (myMap.get(key).isDefined) { //Null pointer exception is thrown here
        //Do stuff
      }
  }
}

使用该方法,一次只能从单个线程访问TrieMap

此外,该测试最好通过以下方式完成:

myMap.get(key).foreach{ value =>
  ???
}
© www.soinside.com 2019 - 2024. All rights reserved.