akka Actor 中的可变集合 return NullPointerException
Mutable collections in akka Actor return NullPointerException
我有一个调用 websocket 并在每次从 web socket 收到更新时更新地图的 actor。演员在命令的另一点使用了同一张地图。
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
是线程安全的,不会出现此类问题。有什么建议吗?
你应该在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 =>
???
}
我有一个调用 websocket 并在每次从 web socket 收到更新时更新地图的 actor。演员在命令的另一点使用了同一张地图。
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
是线程安全的,不会出现此类问题。有什么建议吗?
你应该在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 =>
???
}