.NET - 字典锁与ConcurrentDictionary字典、NET、ConcurrentDictionary

2023-09-02 11:49:27 作者:你好狠丶

我无法找到 ConcurrentDictionary 类型足够的信息,所以我想我会问这里。

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

目前,我用的是词典来认为不断被多个线程访问(从一个线程池,线程所以没有确切数额)的所有用户,而且它有同步访问。

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中的线程安全的集合,它似乎是非常可喜的。我想知道,这将是更高效,更易于管理选项,因为我有有之间选择一个正常的词典与同步访问,或有一个 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.

现在考虑这一点。在店内有一个店员,如果你让所有的方式到队伍的前面,并询问店员你有什么卫生纸,他说是,那么你去好吧,我会回复你的时候,我知道我是多么需要,然后你回到了队伍的前面的时候,店里当然可以被抢购一空。这个场景不是prevented一个线程集合。

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.

一个线程安全的集合不,但是,保证连续作业的线程上的所有工作相同的快照,其内部数据结构,这意味着,如果你有code是这样的:

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.Count tree.First(),另一个线程已清除在树中,这意味着其余节点一()返回

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.

有关这种情况下,您可能需要查看是否有问题的集合有一个安全的方式得到你想要的东西,也许你需要重写上面的code,或者您可能需要锁定。

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.