Kam*_*mil 4 c# collections concurrentdictionary concurrent-queue
ConcurrentQueue有TryDequeue方法。
Queue就有Dequeue方法了。
没有ConcurrentDictionary方法Add,但我们有TryAdd。
我的问题是:
这些并发收集方法有什么区别?为什么它们对于并发集合不同?
假设Dictionary<TKey, TValue>您将实现自己的逻辑以确保不会输入重复的键。例如,
if(!myDictionary.ContainsKey(key)) myDictionary.Add(key, value);
Run Code Online (Sandbox Code Playgroud)
但是,当我们有多个线程运行时,我们会使用并发集合,并且它们可能会同时尝试修改字典。
如果两个线程尝试同时执行上述代码,则myDictionary.ContainsKey(key)两个线程可能都返回 false,因为它们都在同时检查并且该密钥尚未添加。然后他们都尝试添加密钥,但其中一个失败了。
阅读该代码的人如果不知道它是多线程的,可能会感到困惑。在添加密钥之前,我检查过以确保该密钥不在字典中。那么我如何获得例外呢?
ConcurrentDictionary.TryAdd通过允许您“尝试”添加密钥来解决这个问题。如果它添加了它返回的值true。如果没有,则返回false. 但它不会与另一个发生冲突TryAdd并抛出异常。
Dictionary您可以通过将 包装在一个类中并在其周围放置语句来自己完成所有这些操作lock,以确保一次只有一个线程进行更改。ConcurrentDictionary只是为您做这件事,而且做得非常好。您不必查看它如何工作的所有细节 - 您只需在知道多线程已被考虑在内的情况下使用它即可。
以下是在多线程应用程序中使用类时需要注意的细节。如果您转到ConcurrentDictionary Class的文档并滚动到底部,您将看到以下内容:
线程安全ConcurrentDictionary 的
所有公共和受保护成员都是线程安全的,并且可以 在多个线程中同时使用。但是,通过 ConcurrentDictionary 实现的接口之一访问的成员(包括扩展方法)不保证线程安全,并且可能需要由调用者同步。
换句话说,多个线程可以安全地读取和修改集合。
在字典类下你会看到:
线程安全
字典可以支持多个 读者并发,只要集合不被修改。即便如此,通过集合进行枚举本质上并不是线程安全的过程。在枚举与写访问发生冲突的极少数情况下,必须在整个 枚举期间锁定集合 。要允许多个线程访问集合以进行读写,您必须实现自己的同步。
多个线程可以读取键,但如果多个线程要写入,那么您需要以某种方式检查lock字典以确保一次只有一个线程尝试更新。
Dictionary<TKey, TValue>公开一个Keys集合和Values集合,以便您可以枚举键和值,但如果另一个线程要修改字典,它会警告您不要尝试这样做。在添加或删除项目时无法枚举某些内容。如果您需要迭代键或值,则必须锁定字典以防止迭代期间更新。
ConcurrentDictionary<TKey, TValue>假设将有多个线程读取和写入,因此它甚至不会公开键或值集合供您枚举。
| 归档时间: |
|
| 查看次数: |
2320 次 |
| 最近记录: |