.NET - 字典锁定与 ConcurrentDictionary [英] .NET - Dictionary locking vs. ConcurrentDictionary

查看:34
本文介绍了.NET - 字典锁定与 ConcurrentDictionary的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我找不到关于 ConcurrentDictionary 类型的足够信息,所以我想在这里询问一下.

I couldn't find enough information on ConcurrentDictionary types, so I thought I'd ask about it here.

目前,我使用 Dictionary 来保存由多个线程(来自线程池,因此没有确切数量的线程)不断访问的所有用户,并且它具有同步访问.

Currently, I use a Dictionary to hold all users that is accessed constantly by multiple threads (from a thread pool, so no exact amount of threads), and it has synchronized access.

我最近发现.NET 4.0中有一套线程安全的集合,看起来很讨人喜欢.我想知道什么是更有效且更易于管理"的选项,因为我可以选择使用具有同步访问的普通 Dictionary 或使用 ConcurrentDictionary这已经是线程安全的.

I recently found out that there was a set of thread-safe collections in .NET 4.0, and it seems to be very pleasing. I was wondering, what would be the 'more efficient and easier to manage' option, as I have the option between having a normal Dictionary with synchronized access, or have a ConcurrentDictionary which is already thread-safe.

参考 .NET 4.0 的 ConcurrentDictionary

推荐答案

可以以不同的方式看待线程安全集合与非线程安全集合.

A thread-safe collection vs. a non-threadsafe-collection can be looked upon in a different way.

考虑一家没有店员的商店,除了在结账时.如果人们不负责任地行事,您就会遇到很多问题.例如,假设客户从金字塔罐中取出罐头,而店员目前正在建造金字塔,那么一切都会崩溃.或者,如果两个顾客同时到达同一商品,谁会赢?会打架吗?这是一个非线程安全的集合.有很多方法可以避免问题,但它们都需要某种锁定,或者以某种方式进行显式访问.

Consider a store with no clerk, except at checkout. You have a ton of problems if people don't act responsibly. For instance, let's say a customer takes a can from a pyramid-can while a clerk is currently building the pyramid, all hell would break loose. Or, what if two customers reaches for the same item at the same time, who wins? Will there be a fight? This is a non-threadsafe-collection. There's plenty of ways to avoid problems, but they all require some kind of locking, or rather explicit access in some way or another.

另一方面,考虑一家在办公桌前有店员的商店,您只能通过他购物.你排队,向他要一件物品,他把它拿回来给你,你就出线了.如果您需要多件物品,您每次往返只能拿起尽可能多的物品,但您需要小心避免霸占店员,这会激怒您身后排队的其他顾客.

On the other hand, consider a store with a clerk at a desk, and you can only shop through him. You get in line, and ask him for an item, he brings it back to you, and you go out of the line. If you need multiple items, you can only pick up as many items on each roundtrip as you can remember, but you need to be careful to avoid hogging the clerk, this will anger the other customers in line behind you.

现在考虑这个.在只有一名店员的商店里,如果你一直走到队伍的前面,问店员你有卫生纸吗",他说有",然后你说好的,我"当我知道我需要多少时,我会回复你",然后当你回到队伍的最前面时,商店当然可以卖光了.线程安全集合不会阻止这种情况.

Now consider this. In the store with one clerk, what if you get all the way to the front of the line, and ask the clerk "Do you have any toilet paper", and he says "Yes", and then you go "Ok, I'll get back to you when I know how much I need", then by the time you're back at the front of the line, the store can of course be sold out. This scenario is not prevented by a threadsafe collection.

线程安全集合保证其内部数据结构始终有效,即使从多个线程访问也是如此.

A threadsafe collection guarantees that its internal data structures are valid at all times, even if accessed from multiple threads.

非线程安全集合没有任何此类保证.例如,如果您在一个线程上向二叉树添加某些内容,而另一个线程正忙于重新平衡树,则无法保证该项目会被添加,或者即使该树之后仍然有效,它也可能被损坏到无法预期的程度.

A non-threadsafe collection does not come with any such guarantees. For instance, if you add something to a binary tree on one thread, while another thread is busy rebalancing the tree, there's no guarantee the item will be added, or even that the tree is still valid afterwards, it might be corrupt beyond hope.

然而,线程安全集合并不能保证线程上的顺序操作都在其内部数据结构的同一个快照"上工作,这意味着如果您有这样的代码:

A threadsafe collection does not, however, guarantee that sequential operations on the thread all work on the same "snapshot" of its internal data structure, which means that if you have code like this:

if (tree.Count > 0)
    Debug.WriteLine(tree.First().ToString());

你可能会得到一个 NullReferenceException 因为在 tree.Counttree.First() 之间,另一个线程已经清除了树中的剩余节点,这意味着 First() 将返回 null.

you might get a NullReferenceException because inbetween tree.Count and tree.First(), another thread has cleared out the remaining nodes in the tree, which means First() will return null.

对于这种情况,您要么需要查看有问题的集合是否有一种安全的方式来获取您想要的东西,也许您需要重写上面的代码,或者您可能需要锁定.

For this scenario, you either need to see if the collection in question has a safe way to get what you want, perhaps you need to rewrite the code above, or you might need to lock.

这篇关于.NET - 字典锁定与 ConcurrentDictionary的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆