将元素插入Scala可变Map会引发错误

时间:2014-03-06 17:39:15

标签: scala map

我正在尝试将元素插入到可变映射中,并且在尝试时,我得到了如下异常:

 java.lang.ArrayIndexOutOfBoundsException: 62388
 at scala.collection.mutable.HashTable$class.resize(HashTable.scala:255)
 at scala.collection.mutable.HashTable$class.scala$collection$mutable$HashTable$$addEntry0(HashTable.scala:151)
 at scala.collection.mutable.HashTable$class.findOrAddEntry(HashTable.scala:163)
 at scala.collection.mutable.HashMap.findOrAddEntry(HashMap.scala:39)
 at scala.collection.mutable.HashMap.$plus$eq(HashMap.scala:89)
 at scala.collection.mutable.HashMap.$plus$eq(HashMap.scala:39)
 at test.testMethod(AkkaLoadTest.scala:165)
 at test.testMethod(AkkaLoadTest.scala:27)
 at rait$PriceRequestWorker$$anonfun$receive$2.applyOrElse(AkkaLoadTest.scala:224)
 at akka.actor.ActorCell.receiveMessage(ActorCell.scala:425)
 at akka.actor.ActorCell.invoke(ActorCell.scala:386)
 at akka.dispatch.Mailbox.processMailbox(Mailbox.scala:230)
 at akka.dispatch.Mailbox.run(Mailbox.scala:212)
 at akka.dispatch.ForkJoinExecutorConfigurator$MailboxExecutionTask.exec(AbstractDispatcher.scala:502)
 at scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260)
 at scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339)
 at scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979)
 at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107)

看起来很奇怪!这是我的工作:

  var mutableMap= scala.collection.mutable.Map[String, List[String]]()

我在我的对象和testMethod中全局声明了Map,我执行以下操作:

if(anotherList.size > 0) {
  mutableMap.get(id) match {
    case Some(entries) => /* Do nothing as the entry is already available in the map */
    case None => {
      mutableMap+= id-> anotherList
    }
  }
}

将id作为另一个参数传递给实现上述代码的方法。我很困惑地看到在我看来根本不相关的例外!有什么想法吗?

1 个答案:

答案 0 :(得分:5)

可变集合不是线程安全的。您是否有机会从不同的线程同时访问或更新它?鉴于你说你的地图是“全球的”,并且你使用Akka演员,这看起来像是灾难的秘诀。你不应该在不同的演员之间分享状态。

您可能会尝试通过

强制同步地图
import scala.collection.mutable
val mutableMap = new mutable.HashMap[String, List[String]]
  with mutable.SynchronizedMap[String, List[String]]()

如果问题消失,您就会知道线程问题。然后你会重新考虑你的状态模型;如果您真的想要共享地图并且SynchronizedMap的效果太糟糕,那么您可以尝试scala.collection.concurrent.Map

之类的替代方案