【问题标题】:Does .NET have a Dictionary implementation that is equivalent to Java's ConcurrentHashMap?.NET 是否有与 Java 的 ConcurrentHashMap 等效的 Dictionary 实现?
【发布时间】:2010-09-21 22:53:35
【问题描述】:

为那些可能不了解 Java API 的 .NET 专家回顾一下:

Java 中的ConcurrentHashMap 具有用于常见 Map 修改操作的原子方法(即不需要外部锁定),例如:

putIfAbsent(K key, V value)
remove(Object key, Object value)
replace(K key, V value)

它还允许在没有锁定的情况下对键集进行迭代(它在迭代开始时获取一个副本)并且get() 操作通常可以与对put() 的调用交错而不阻塞(它使用细粒度的锁条带IIRC )。

无论如何,我的问题是:.NET 有等效的 Dictionary 实现吗?

我想更笼统地说,我很想知道 .NET 是否有一组更通用的线程安全集合库。或一般的并发实用程序 - 相当于 Doug Leajava.util.concurrent 库。

【问题讨论】:

  • 这里真的需要java标签吗?
  • Georgy - 你是对的 - 这是一个 .net 问题,而不是 Java 问题。标记已删除。
  • 我的项目concurrent.codeplex.com 有一个分片字典,它允许多个读取器和写入器,并允许对某些值进行交易。虽然它正在大力开发中......

标签: .net concurrency dictionary map


【解决方案1】:

编辑:这是在 .NET 4 发布之前编写的,当时显然有 ConcurrentDictionary。我把它留在这里作为那些需要 .NET 3.5 的人的参考。

我不知道有什么等同于ConcurrentHashMap

就通用并发实用程序而言 - .NET 提供的功能比 Java 过去提供的基本功能要多一些,例如 MutexManualResetEventAutoResetEventReaderWriterLock;然后是最近的 (.NET 2.0) Semaphore 和 (.NET 3.5) ReaderWriterLockSlim - 当然还有进程范围的线程池。

当 Parallel Extensions 到来时,.NET 4.0 将会发生更大的变化——这应该会使并发更加更简单。同样,Coordination and Concurrency Runtime 终于摆脱了 Microsoft Robotics Studio 的束缚,尽管我不清楚它的确切发展方向(它是 .NET 本身的一部分,还是一个单独的库)。

【讨论】:

  • 我(来自公共 MSDN 博客)的印象是它注定要成为 .NET 4.0 本身的核心部分。
  • 感谢您回答乔恩。 Parallel Extensions 看起来很有趣。只是要明确一点——我不是在拖钓——这不是“Java 拥有比 .net 更好的库”的咆哮。我刚接触 .net,很想看看开箱即用的内容。
  • Marc:CCR 作为 .NET 4.0 的一部分?欢迎提供链接! Serg:别担心,我没有那样想 :)
  • @Jon:因为已经过时但现在你已经更新了,我删除了反对票。 :-)
  • @Jon Harrop:谢谢。将来,如果您在投反对票时发表评论会很有帮助,以使回答者更清楚应该改进的地方。
【解决方案2】:

我不知道。与您正在寻找的最接近的可能是哈希表的同步方法,它返回哈希表周围的(某种)线程安全包装器。不过,它只对多个作者或多个读者是线程安全的。如果我没记错的话,作者和读者的混合不会是线程安全的。

【讨论】:

    【解决方案3】:

    就我个人而言,我发现将单个方法同步通常并不像听起来那么有用。

    通常,您可能希望连续执行相关的“获取”和“放置”,如果另一个线程正在查看相同的值,则您会立即进行线程竞赛。同样(取决于场景)您不希望有人阅读您正在处理的值。

    对于更广泛的方法,只需使用外部Monitorlock(...) 在许多情况下都可以很好地工作。它简单、轻量级,除非您处于线程负载下,绰绰有余。

    对于更复杂的场景,ReaderWriterLockSlim 等内容更加灵活。但我会从简单开始,只有在分析表明存在真正的争用问题时才进行更改。

    正如 Jon 所说,Parallel Extension 带来了一系列全新的高性能同步设备;据我所知(例如hereherehere),这是.NET 4.0 的一部分

    【讨论】:

    • 在Java的ConcurrentHashMap中,个别的get、replace、putIfAbsent等方法是不同步的。他们使用非阻塞算法在大多数负载情况下不加锁地工作。我会看看 ReaderWriterLockSlim - 感谢您的提示。
    【解决方案4】:

    传入的.Net 4.0有一个ConcurrentDictionary类,它有一个方便的GetOrAdd方法。

    public TValue GetOrAdd(
        TKey key,
        Func<TKey, TValue> valueFactory
    )
    

    对于全局服务器缓存非常有用。

    【讨论】:

    • 对于全局服务器缓存,最好使用MemoryCache 对象,否则如果不手动从ConcurrentDictionary 中删除引用的对象,您可能会泄漏内存
    • 注意 GetOrAdd 的 valueFactory 可以多次执行,并且 不是原子的,如 HereHere 所示
    猜你喜欢
    • 2011-03-17
    • 2021-05-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-11
    • 2014-11-27
    • 2011-04-16
    • 1970-01-01
    相关资源
    最近更新 更多