Я написал игрока Монте-Карло для настольной игры Nine Men's Morris. Все в основном неизменно. Программа включает в себя множество фьючерсов (сотни) и множество модификаций неизменяемых карт. Иногда я получаю сбой со следующим исключением:
java.lang.NullPointerException
at scala.collection.mutable.HashTable$class.elemHashCode(HashTable.scala:154)
at scala.collection.immutable.HashMap.elemHashCode(HashMap.scala:41)
at scala.collection.mutable.HashTable$class.findEntry(HashTable.scala:66)
at scala.collection.immutable.HashMap.findEntry(HashMap.scala:41)
at scala.collection.immutable.HashMap.undo$1(HashMap.scala:132)
at scala.collection.immutable.HashMap.undo$1(HashMap.scala:130)
at scala.collection.immutable.HashMap.makeCopy(HashMap.scala:154)
at scala.collection.immutable.HashMap.makeCopyIfUpdated(HashMap.scala:161)
at scala.collection.immutable.HashMap.update(HashMap.scala:66)
at scala.collection.immutable.Map$class.$plus(Map.scala:66)
at scala.collection.immutable.HashMap.$plus(HashMap.scala:41)
at morris.players.MapBasedMorrisBoard.applyMove(MapBasedMorrisBoard.scala:30)
at morris.players.MonteCarloPlayer$$anonfun$main$1$$anonfun$apply$1.apply(MonteCarloPlayer.scala:77)
at morris.players.MonteCarloPlayer$$anonfun$main$1$$anonfun$apply$1.apply(MonteCarloPlayer.scala:77)
at scala.actors.Futures$$anonfun$2$$anonfun$apply$1.apply(Future.scala:45)
at scala.actors.Futures$$anonfun$2$$anonfun$apply$1.apply(Future.scala:44)
at scala.actors.Reaction.run(Reaction.scala:78)
at scala.actors.FJTask$Wrap.run(Unknown Source)
at scala.actors.FJTaskRunner.scanWhileIdling(Unknown Source)
at scala.actors.FJTaskRunner.run(Unknown Source)
Я использую только неизменные Карты, поэтому мне интересно, вызвано ли это ошибкой в моем собственном коде или, возможно, ошибкой в библиотеке scala. Глядя на трассировку, вы видите, что есть вызовы к изменяемой HashTable дальше по стеку. Может быть, это вызывает проблемы с параллелизмом?
Код внутри моей программы, где происходит исключение, - это просто добавление еще одной коллекции в неизменяемую карту:
myMap ++ (someInteger -> aValue)
Edit:
Та же программа без параллелизма работает без сбоев.