gpt4 book ai didi

c# - 为什么 ConcurrentQueue 和 ConcurrentDictionary 有 "Try"方法——TryAdd、TryDequeue——而不是 Add 和 Dequeue?

转载 作者:太空狗 更新时间:2023-10-30 00:10:01 25 4
gpt4 key购买 nike

ConcurrentQueueTryDequeue 方法。

Queue 只有 Dequeue 方法。

ConcurrentDictionary 中没有Add 方法,但我们有TryAdd 方法。

我的问题是:

这些并发收集方法有什么区别?为什么它们对于并发集合不同?

最佳答案

Dictionary<TKey, TValue>假定您要实现自己的逻辑以确保不输入重复键。例如,

if(!myDictionary.ContainsKey(key)) myDictionary.Add(key, value);

但是当我们有多个线程运行时,我们会使用并发集合,并且它们可能同时尝试修改字典。

如果两个线程试图同时执行上面的代码,有可能myDictionary.ContainsKey(key)可能会为两个线程返回 false,因为它们同时进行检查并且尚未添加该 key 。然后他们都尝试添加 key ,但其中一个失败了。

阅读该代码但不知道它是多线程的人可能会感到困惑。在我添加它之前,我检查以确保该键不在字典中。。那么我如何获得异常呢?

ConcurrentDictionary.TryAdd通过允许您“尝试”添加 key 来解决这个问题。如果它添加它返回的值 true .如果不是,则返回 false .但它不会做的是与另一个 TryAdd 发生冲突。并抛出异常。

您可以通过包装 Dictionary 来自己完成所有这些工作在类里面并投入lock围绕它的语句以确保一次只有一个线程进行更改。 ConcurrentDictionary只是为你做,而且做得很好。您不必查看其工作原理的所有详细信息 - 您只需在知道多线程已被考虑在内的情况下使用它即可。

这是在多线程应用程序中使用类时要查找的详细信息。如果您查看 ConcurrentDictionary Class 的文档滚动到底部你会看到这个:

Thread Safety
All public and protected members of ConcurrentDictionary are thread-safe and may be used concurrently from multiple threads. However, members accessed through one of the interfaces the ConcurrentDictionary implements, including extension methods, are not guaranteed to be thread safe and may need to be synchronized by the caller.

换句话说,多个线程可以安全地读取和修改集合。

Dictionary Class你会看到这个:

Thread Safety
A Dictionary can support multiple readers concurrently, as long as the collection is not modified. Even so, enumerating through a collection is intrinsically not a thread-safe procedure. In the rare case where an enumeration contends with write accesses, the collection must be locked during the entire enumeration. To allow the collection to be accessed by multiple threads for reading and writing, you must implement your own synchronization.

多个线程可以读取 key ,但是如果多个线程要写入 那么您需要以某种方式lock确保一次只有一个线程尝试更新的字典。

Dictionary<TKey, TValue>公开一个 Keys收藏与Values collection 以便您可以枚举键和值,但是如果另一个线程将要修改字典,它会警告您不要尝试这样做。在添加或删除项目时,您无法枚举某些内容。如果您需要遍历键或值,则必须锁定字典以防止在该迭代期间进行更新。

ConcurrentDictionary<TKey, TValue>假设会有多个线程读写,所以它甚至不会公开键或值集合供您枚举。

关于c# - 为什么 ConcurrentQueue 和 ConcurrentDictionary 有 "Try"方法——TryAdd、TryDequeue——而不是 Add 和 Dequeue?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38396477/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com