【问题标题】:Mutating a HashMap concurrently in Scala without Actors在没有 Actor 的情况下在 Scala 中同时改变 HashMap
【发布时间】:2012-07-15 15:15:42
【问题描述】:

我想要做的是开始使用Map 的一些实现,并通过迭代并行集合将数据累积到其中。密钥可以在线程之间“重叠”,因为密钥是概率生成的(与随机数生成有关)。

例如。线程 1 想要将 key = A value = 1 添加到映射中。如果它已经存在,则将 1 添加到现有值(因为值是 1) - 如果不存在,则创建映射。同时,另一个线程有 key = A 和 value = 2,并且想做同样的事情。

有没有办法在不创建整个Actor 系统的情况下做到这一点?

Java 库中的ConcurrentHashMap 看起来很有趣,但是关于跨线程更新映射的安全性,“弱一致性”迭代器让我感到困扰..

【问题讨论】:

  • 还有其他同步方法.. 真正归结为所需的结果/语义是什么。
  • wrt ConcurrentHashMap 迭代器,请参阅:stackoverflow.com/questions/3768554/… 如果这些语义不“正确”,那是什么?它类似于在允许不可重复(包括幻像)读取的 READ COMMITTED 和 DB 事务中的 SERIALIZABLE 之间进行选择......这是“正确的”?

标签: scala concurrency parallel-collections


【解决方案1】:

如果没有 Actors,这是一件非常微不足道的事情。

class CountMap[K <: AnyRef](mapSize: Int = 16) extends ConcurrentHashMap[K, AtomicLong](mapSize) {
  def addCount(key: K): Long = (get(key) match { // Check value for key
    case null =>  // If not mapped yet
      val al = new AtomicLong(0) // Create a new memory slot to keep the count in that is thread safe
      putIfAbsent(key, al) match { // Try to put our memory slot in atomically
        case null => al // If we succeeded then our memory slot should be used
        case some => some // if there already was a memory slot, use that one
      }
    case some => some // If there already was a memory slot, use that one
    }).incrementAndGet() // increment and get the current value of the slot associated with the given key

  def getCount(key: K): Long = get(key) match { // get the memory slot associated with the key
    case null => 0L // if none, say it's 0
    case some => some.get() // if some get its value
  }
}

【讨论】:

  • 有趣 - 我想我会创建一个 this 的实例并使用它来跨线程改变值?
  • 我不同意这是“非常微不足道的”。它需要详细了解 ConcurrentHashMap 的内部工作原理。扩展这样一个类的方法可能比正确方法多得多。
  • Rick-777:它需要 0 详细了解 CHM 的内部工作原理。您只需要知道存在 ConcurrentMap/AtomicLong 并且您可以阅读 JavaDoc。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-06-15
  • 2015-02-23
  • 1970-01-01
  • 2011-08-28
  • 2023-01-10
  • 1970-01-01
  • 2018-06-20
相关资源
最近更新 更多