5

回顾那些可能不知道 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库。

4

4 回答 4

16

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

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

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

于 2010-01-02T22:14:34.313 回答
3

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

我不知道有什么等价于ConcurrentHashMap.

就通用并发实用程序而言 - .NET 始终提供比 Java 过去提供的基础知识多一点的功能Mutex,包括ManualResetEventAutoResetEventReaderWriterLock; 然后是最近的(.NET 2.0)Semaphore和(.NET 3.5)ReaderWriterLockSlim——当然还有进程范围的线程池。

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

于 2008-11-12T09:16:43.263 回答
2

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

于 2008-11-12T09:25:25.273 回答
2

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

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

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

对于更复杂的场景,诸如ReaderWriterLockSlimetc 之类的东西更加灵活。但我会从简单开始,只有在分析显示存在真正的争用问题时才进行更改。

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

于 2008-11-12T09:46:44.450 回答