joesan
joesan

Reputation: 15385

Inserting elements to a Scala mutable Map throws error

I'm trying to insert elements to a mutable Map and as I tried, I got the exception as below:

 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)

It looks strange through! Here is what I do:

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

I declare the Map globally in my object and in my testMethod, I do the following:

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
    }
  }
}

The id is passed as another parameter to the method the above code is implemented. I'm baffled to see the exception that in my sense has got no relevance at all! Any ideas?

Upvotes: 0

Views: 448

Answers (1)

0__
0__

Reputation: 67280

Mutable collections are not thread safe. Are you by any chance accessing or updating it concurrently from different threads? Given that you say your map is "global", and you use Akka actors, this looks like a recipe for disaster. You should not share state between different actors.

You might try to force synchronize the map via

import scala.collection.mutable
val mutableMap = new mutable.HashMap[String, List[String]]
  with mutable.SynchronizedMap[String, List[String]]()

If the problem disappears, you know that threading is the issue. You would then rethink your state model; if you really want a shared map and performance with SynchronizedMap is too bad, you could try alternatives such as scala.collection.concurrent.Map

Upvotes: 6

Related Questions