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

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

问题描述

我找不到关于 ConcurrentDictionary 类型的足够信息,所以我以为我会在这里询问。



目前,我使用字典来容纳由多个线程(从线程池,因此没有确切的线程)不断访问的所有用户,并且它具有同步访问。



我最近发现.NET 4.0中有一组线程安全的集合,似乎非常愉快。我想知道,更有效和更容易管理的选项是什么,因为我有选择在一个正常的字典与同步访问,或有一个code> ConcurrentDictionary 已经是线程安全的。



参考.NET 4.0的 ConcurrentDictionary

解决方案

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



除了在结帐之外,考虑没有店员的商店。如果人们不负责任地行事,你有很多问题。例如,假设一个客户从金字塔罐头上拿出罐子,而店员目前正在建设金字塔,所有的地狱都会松动。或者,如果两个客户同时到达同一个项目,谁赢了?会有战斗吗?这是一个非线程安全的集合。有很多方法来避免问题,但是它们都需要某种锁定,或者以某种方式显式访问。



另一方面,考虑一个商店在一张书桌上有一个店员,你只能通过他购物。你排队,问他一个项目,他把它带回来,你走出去。如果您需要多件物品,您只能在每次往返时候拿到尽可能多的物品,但您需要小心避免囤积店员,否则会让其他顾客感到愤怒。



现在考虑一下。在一个店员的店里,如果你一路走到线路的前方,请问店员你有厕所纸,他说是,然后你去好吧,我当我知道我需要多少时,会回复你,那么当你回到线路的前面时,商店当然可以卖完了。线程安全集合不会阻止这种情况。



线程安全集合保证其内部数据结构始终有效,即使从多个线程访问。 >

非线程安全集合不附带任何此类保证。例如,如果您在一个线程上添加一个二叉树,而另一个线程正忙于重新平衡树,则不能保证该项目将被添加,或者甚至该树仍然有效,否则可能已经破坏了希望。



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

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

您可能会收到NullReferenceException,因为中间 tree.Count tree.First(),另一个线程清除了树中的其余节点,这意味着 First()将返回 null



对于这种情况,您需要查看相关的集合是否具有安全的方式来获得你想要的,也许你需要重写上面的代码,或者你可能需要锁定。


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.

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.

Reference to .NET 4.0's 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());

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天全站免登陆