Exception 并发程序中带有不可变映射的Scala bug?

Exception 并发程序中带有不可变映射的Scala bug?,exception,scala,concurrency,immutability,Exception,Scala,Concurrency,Immutability,我为九人莫里斯棋盘游戏写了一个蒙特卡洛球员。一切基本上都是不变的。该计划涉及大量的未来(数百)和大量修改不可变映射。有时我会遇到崩溃,但有以下例外: java.lang.NullPointerException at scala.collection.mutable.HashTable$class.elemHashCode(HashTable.scala:154) at scala.collection.immutable.HashMap.elemHashCode(HashMap

我为九人莫里斯棋盘游戏写了一个蒙特卡洛球员。一切基本上都是不变的。该计划涉及大量的未来(数百)和大量修改不可变映射。有时我会遇到崩溃,但有以下例外:

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库中的错误引起的。当查看跟踪时,您可以看到,在堆栈的更深处有对可变哈希表的调用。也许这会导致并发问题

发生异常的程序中的代码只是将另一个集合添加到不可变映射中:

myMap ++ (someInteger -> aValue)
编辑:
没有并发的同一个程序可以完美地运行。

它肯定会导致并发问题。至少要把地图和同步地图混合起来


但请注意,这并没有给您任何事务保证。它只是确保地图不会在你脚下断裂。

我已经为Scala库提交了一份错误报告。事实证明,这是一个已知的问题。HashMap(在Scala中用作标准映射类型)的实现不适合在并发程序中使用,因为在后台,它使用可变类型。这也可以在堆栈跟踪中观察到。Scala人员希望在2.8中替换实现

作为一种解决方法,建议使用TreeHashMap,它确实是不可变的。我已经这样做了,可以确认它是有效的


执行此操作:使用SynchronizedMap[Int,MorrisColor.Value]新建scala.collection.immutable.HashMap[Int,MorrisColor.Value]()会产生一个错误:(错误覆盖方法excl in…)有什么想法吗?当我使用来自immutable的映射时,SynchronizedMap特性在包中是可变的。你确定这是明智之举?我真的必须将SynchronizedMap混合到一个不可变的类型中吗?@ziggystar-不,我认为你根本不应该这样做。不可变映射确实在内部使用同步,这很奇怪,但“客户机”不需要关心itZiggy,您说过“我只使用可变映射”,所以我假设您使用的是可变映射。:-)不,对于immutable,您不应该做任何事情——但可能确实存在一个bug。您使用的Scala版本是什么?@Daniel抱歉,这是一个打字错误。我只使用堆栈跟踪中可以看到的不可变映射。这个bug发生在2.7.7上,实际上我非常希望这是Scala中的一个bug,我已经提出了要求,只是为了得到一些整合,以便将报告发布到Scala bugtracker。我在实现对“libscala”的STM支持时遇到了同样的问题。该错误同时出现在scala 2.8和2.7.7中。