【问题标题】:Immutable Map with var or Mutable map with val?带有 var 的不可变映射或带有 val 的可变映射?
【发布时间】:2018-06-20 10:29:08
【问题描述】:

以下两个 sn-ps 中哪个更高效且行为正确?

// snippet 1
var map = Map[String, Int]()   // immutable map with var
map.synchronized(map += "hello" -> 1)
map.synchronized(map -= "hello")

// snippet 2
val mmap = scala.collection.mutable.Map[String, Int]()
mmap.synchronized(mmap += "hello" -> 1)
mmap.synchronized(mmap -= "hello")

编辑:我正在寻找同时访问地图的情况,其中多个不同的参与者共享同一个地图并想要修改它。链接的问题还涉及varval 的一般情况,而我需要对Map 集合类型有所了解。

【问题讨论】:

  • 上述问题没有明确处理并发。
  • 有什么原因你不能把这张地图放在一个演员里面,让其他演员使用消息来修改/阅读它?
  • 我可以尝试,但需要复制,并且我需要演员之间的共享状态,这通过实现消息传递太过分了
  • @soote 再想一想,你是对的!我将使用适当的演员模型来实现它。

标签: scala concurrency immutability scala-collections mutable


【解决方案1】:

这取决于可变对象和不可变对象都有各自的优缺点。

不可变对象使并发编程更容易、更安全,而且您可以轻松推断它们。围绕 JVM 并发发生的大多数运行时错误是由于共享可变状态造成的。

如果你的对象变得更大,仅仅为了保持不可变状态而复制对象是没有意义的。在设计算法时,您必须明智地思考。

【讨论】:

    【解决方案2】:

    soote:您是否有理由不能将此地图放置在一个演员中,并让其他演员使用消息来修改/读取它?

    Jus12:@soote 转念一想,你是对的!我将使用适当的演员模型来实现它。

    soote 确实是对的:因为您显然使用的是演员系统,所以地图应该驻留在演员中。通常,当在actor内部表示可变状态时,应该使用带有var的不可变数据结构,而不是带有val的可变数据结构。这样做的原因是为了防止该状态泄漏到参与者的边界之外。下面是一个使用 Akka 的具体示例:

    case object GetState
    case class Add(key: String, value: Int)
    case class Remove(key: String)
    
    class MyActor extends Actor {
      val state = mutable.Map[String, Int]()
    
      def receive = {
        case GetState =>
          sender ! state
        case Add(k, v) =>
          state += (k -> v)
        case Remove(k) =>
          state -= k
      }
    }
    

    当上述actor收到GetState消息时,它会将其内部映射发送给发送者。由于地图是可变的,因此发送者现在可以从参与者外部修改该地图,从而允许破坏参与者的状态。为防止这种泄漏,请将可变性限制为 Actor 本身:

    class MyActor extends Actor {
      var state = Map[String, Int]() // immutable map
    
      def receive = {
        case GetState =>
          sender ! state
        case Add(k, v) =>
          state = state + (k -> v)
        case Remove(k) =>
          state = state - k
      }
    }
    

    现在MyActor 可以安全地将其状态发送给其他参与者,因为它的状态是一个不可变的映射。

    【讨论】:

    • 另一个答案中的评论呢? If your objects become larger, making a copy of the object just for the sake of maintaining an immutable state does not make sense. 地图确实很大,大约有 10k 个条目。
    猜你喜欢
    • 2020-10-14
    • 1970-01-01
    • 2017-03-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-29
    • 1970-01-01
    • 2012-01-05
    相关资源
    最近更新 更多