如何合并collection.concurrent.Map

时间:2014-11-03 20:46:47

标签: scala collections

合并两个并发映射的最佳方法是什么。

这是我目前的impl:

private def merge[A, B](map1: concurrent.Map[A, B], map2: concurrent.Map[A, B]) : concurrent.Map[A, B] = {
  val mergedMap = map1 ++ map2
  val concurrentMap = new TrieMap[A, B]()
  mergedMap.foreach {case (k, v) => concurrentMap.put(k, v)}
  concurrentMap
}

1 个答案:

答案 0 :(得分:2)

您必须在地图访问中处理竞争条件。在您的代码中,当您合并两个地图并同时修改它们时,您可能会错过元素甚至“脱离边缘”。

我建议如下(但需要更严格地输入TrieMap):

private def merge[A, B](map1: TrieMap[A, B], map2: TrieMap[A, B]) : TrieMap[A, B] = {
  val res = map1.snapshot()
  res ++= map2.snapshot()
  res
}

(没试过这个,但我希望这个想法很明确。)

如果您不关心此方法中的并发访问,您也可以简单地使用构建器:

private def merge[A, B](map1: concurrent.Map[A, B], map2: concurrent.Map[A, B]) : concurrent.Map[A, B] = {
  val builder = TrieMap.newBuilder[A, B]
  map1.foreach(builder += _)
  map2.foreach(builder += _)
  builder.result()
}

这将避免创建任何中间结构。