ConcurrentDictionary 线程安全吗?我可以将它用于静态缓存吗?

发布于 2024-11-24 09:02:30 字数 192 浏览 2 评论 0原文

基本上,如果我想执行以下操作:

public class SomeClass
{
    private static ConcurrentDictionary<..., ...> Cache { get; set; }
}

这是否可以让我避免在各处使用lock

Basically, if I want to do the following:

public class SomeClass
{
    private static ConcurrentDictionary<..., ...> Cache { get; set; }
}

Does this let me avoid using locks all over the place?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

命比纸薄 2024-12-01 09:02:30

是的,它是线程安全的,并且它避免您到处使用锁(无论这意味着什么)。当然,这只会为您提供对此字典中存储的数据的线程安全访问,但如果数据本身不是线程安全的,那么您当然需要同步对其的访问。例如,假设您在此缓存中存储了一个 List。现在,thread1 获取此列表(以线程安全的方式,因为并发字典保证了这一点),然后开始枚举此列表。与此同时,thread2 从缓存中获取相同的列表(以线程安全的方式,因为并发字典保证了这一点)并写入列表(例如,它添加了一个值)。结论:如果你没有同步thread1,它就会遇到麻烦。

就将其用作缓存而言,这可能不是一个好主意。对于缓存,我会向您推荐框架中已内置的内容。例如 MemoryCache 等类。其原因是 System.Runtime.Caching< 中内置的内容/code>程序集是为缓存而显式构建的 =>它可以处理诸如内存不足时数据自动过期、缓存过期项回调等事务,您甚至可以使用 memcached、AppFabric 等将缓存分布到多个服务器上,...不可能梦想有一个并发字典。

Yes, it is thread safe and yes it avoids you using locks all over the place (whatever that means). Of course that will only provide you a thread safe access to the data stored in this dictionary, but if the data itself is not thread safe then you need to synchronize access to it of course. Imagine for example that you have stored in this cache a List<T>. Now thread1 fetches this list (in a thread safe manner as the concurrent dictionary guarantees you this) and then starts enumerating over this list. At exactly the same time thread2 fetches this very same list from the cache (in a thread safe manner as the concurrent dictionary guarantees you this) and writes to the list (for example it adds a value). Conclusion: if you haven't synchronized thread1 it will get into trouble.

As far as using it as a cache is concerned, well, that's probably not a good idea. For caching I would recommend you what is already built into the framework. Classes such as MemoryCache for example. The reason for this is that what is built into the System.Runtime.Caching assembly is, well, explicitly built for caching => it handles things like automatic expiration of data if you start running low on memory, callbacks for cache expiration items, and you would even be able to distribute your cache over multiple servers using things like memcached, AppFabric, ..., all things that you would can't dream of with a concurrent dictionary.

冷月断魂刀 2024-12-01 09:02:30

您可能仍然需要像在数据库中使用事务一样使用锁定。 “并发”部分意味着字典将在多个线程中继续正确运行。

并发集合中内置了 TryGetValue 和 TryRemove,它们确认有人可能会先删除某个项目。细粒度的锁定是内置的,但您仍然需要考虑在这些情况下该怎么做。对于缓存来说,这通常并不重要——即它是幂等操作。

回复:缓存。我觉得这取决于您在缓存中存储的内容+您用它做什么。使用对象会产生铸造成本。正如上面所建议的,对于大多数基于 Web 的事物来说,MemCache 可能更适合。

You still may need to use locking in the same way that you might need a transaction in a database. The "concurrent" part means that the dictionary will continue to function correctly across multiple threads.

Built into the concurrent collection are TryGetValue and TryRemove which acknowledge that someone might delete an item first. Locking at a granular level is built in, but you still need to think about what to do in these situations. For Caching, it often doesn't matter -- i.e. it's an idempotent operation.

re: caching. I feel that it depends on what you are storing in the cache + what you are doing with it. There are casting costs associated with using an object. Probably for most web based things MemCache is better suited as suggested above.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文