多线程程序中key个数固定的情况下用Dictionary代替ConcurrentDictionary是否可以?
我知道在多线程程序中,我们需要使用 ConcurrentDictionary、ConcurrentBag 等线程安全集合。但在我的情况下,字典中的键数是固定的,我有确切的 5 个键,在程序执行之前我已经知道这些键,因此我可以初始化字典的键。所以我的想法是,因为键的数量不会改变,所以我实际上可以使用 Dictionary
而不是 ConcurrentDictionary
,而我想这样做的原因是,是因为集合不会在内部调整大小,所以不会出现线程1在线程2添加新元素后尝试更新元素然后导致调整大小的情况,从而导致线程1更新失败。我的理解正确吗?
更多信息:
我没有可以由所有线程更新的共享键/值对,每个线程仅更新特定的键/值对,并且 TKey 是唯一的字符串,TValue 是简单的类类型
I know in multithreading program, we need to use ConcurrentDictionary
, ConcurrentBag
etc those thread-safe collection. But in my situation, the number of keys in Dictionary is fixed, I have exact 5 keys which I already know before the program executes so I can initialize the dictionary's key. So my thinking is, because the number of the keys is not going to change, I can actually use Dictionary
instead of ConcurrentDictionary
, and the reason I am thinking to do this, is because the collection won't resize internally, so there won't be a situation when thread1 try to update an element after thread2 adds a new element then cause resizing, which makes thread1's update fail. Is my understanding correct?
More information:
I don't have a shared key/value pair that can be updated by all threads, each thread just update a particular key/value pair and TKey is a unique string, TValue is simple class type
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
Dictionary
类的文档 明确指出:因此,根据文档,如果您在不同步的情况下通过多个线程修改字典,则已进入“未定义行为”领域。意味着“任何事情”都可能发生,并且无论发生什么都不会是错误。保修已被违反,并且 Microsoft 不会关心因错误使用其产品而对您造成的任何损害。
也就是说,知道
Dictionary
类是如何实现的,使用它不太可能会遇到任何问题如果您遵循问题中描述的非常严格的使用模式,则以无锁方式使用Dictionary
。由您决定是否可以依赖您使用的 API 的实现细节,而不是已发布的文档。作为旁注,请注意,通常在小型
List
或数组中连续搜索值优于在小型基于哈希的Dictionary中搜索值;
。临界点取决于密钥的类型,并且可能多达 50 个元素或更多。另外,为了每个线程存储一个值,您可能会发现ThreadLocal
类很有用。The documentation of the
Dictionary<TKey, TValue>
class states explicitly that:So, based on the documentation, if you modify the dictionary by multiple threads without synchronization, you have entered the "undefined behavior" territory. Meaning that "anything" can happen, and whatever happens will not be a bug. The warranty has been breached, and Microsoft couldn't care less about any damages that have occurred to you, after using their products incorrectly.
That said, and knowing how the
Dictionary<TKey, TValue>
class is implemented, it's unlikely that you'll have any issues by using aDictionary<TKey, TValue>
in a lock-free manner, if you follow the very strict usage pattern that you describe in your question. It's up to you decide if it's OK to rely on implementation details of the API that you use, instead of the published documentation.As a side note, be aware that in general searching serially for a value in a small
List<T>
or array outperforms searching for a value in a small hash-basedDictionary<TKey, TValue>
. The tipping point depends on the type of the key, and might be as large as 50 elements or more. Also for storing one value per thread, you might find theThreadLocal<T>
class useful.总结
我真的想要它。我可以吗?是的,但是。
如果
,则不需要锁定当前的实现(即
Dictionary
就可以了),因为字典本身不会改变,并且只有一个消费者访问每个值。可以吗?并非如此
一般来说,使用可以工作的代码但使用对于给定场景有更好替代方案的结构是不行的。像这样的代码很容易被破坏,除非将其部署到现实生活场景中,否则很难快速找出问题。
Summary
I really want it. Can I? Yes, but.
If
then locking in the current implementation is not needed (i.e.
Dictionary
is fine) because the dictionary itself doesn't change and a single consumer accesses each value.Is it OK? Not really
Generally, it is not OK to use code which works but uses structures that have better alternatives for a given scenario. Code like this is very easy to break without knowing until it is deployed in a real life scenario and even then it's hard to find out the issue quickly.