Изменяемые коллекции в akka Actor возвращают исключение NullPointerException - PullRequest
0 голосов
/ 30 мая 2020

У меня есть актер, который вызывает веб-сокет и обновляет карту каждый раз, когда он получает обновление из веб-сокета. та же карта используется актером в другой точке команды.

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 будет потокобезопасным и не будет иметь таких проблем. Есть предложения?

1 Ответ

4 голосов
/ 30 мая 2020

Вы должны выполнить как можно больше обработки в методе 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 =>
  ???
}
...