并发字典VS 字典

发布于 2024-10-22 01:47:30 字数 991 浏览 16 评论 0原文

正如 MSDN 所说

ConcurrentDictionary Class 表示可以被多个线程并发访问的线程安全的键值对集合。

但据我所知,System.Collections.Concurrent 类是为 PLINQ 设计的。

我有 Dictionary 它将在线客户端保留在服务器中,并且当我可以访问它时,我通过锁定对象来使其线程安全。

在我的情况下,我可以安全地将 Dictionary 替换为 ConcurrentDictionary 吗?更换后性能会提高吗?

这里在第 5 部分 Joseph Albahari 中提到它是为并行编程而设计的

  • 并发集合是针对并行编程进行了调整。除了高度并发的场景之外,传统集合的性能都优于它们。
  • 线程安全集合并不保证使用它的代码是线程安全的。
  • 如果在另一个线程正在修改并发集合时枚举该集合,则不会引发异常。相反,您会得到新旧内容的混合体。
  • List 没有并发版本。
  • 并发栈、队列、包类在内部都是用链表实现的。这使得它们的内存效率低于非并发 Stack 和 Queue 类,但更适合并发访问,因为链表有利于无锁或低锁实现。 (这是因为将节点插入链表只需要更新几个引用,而将元素插入类似列表的结构可能需要移动数千个现有元素。)

As MSDN says

ConcurrentDictionary<TKey, TValue> Class Represents a thread-safe collection of key-value pairs that can be accessed by multiple threads concurrently.

But as I know, System.Collections.Concurrent classes are designed for PLINQ.

I have Dictionary<Key,Value> which keeps on-line clients in the server, and I make it thread safe by locking object when I have access to it.

Can I safely replace Dictionary<TKey,TValue> by ConcurrentDictionary<TKey,TValue> in my case? will the performance increased after replacement?

Here in Part 5 Joseph Albahari mentioned that it designed for Parallel programming

  • The concurrent collections are tuned for parallel programming. The conventional collections outperform them in all but highly concurrent scenarios.
  • A thread-safe collection doesn’t guarantee that the code using it will be thread-safe.
  • If you enumerate over a concurrent collection while another thread is modifying it, no exception is thrown. Instead, you get a mixture of old and new content.
  • There’s no concurrent version of List.
  • The concurrent stack, queue, and bag classes are implemented internally with linked lists. This makes them less memory-efficient than the nonconcurrent Stack and Queue classes, but better for concurrent access because linked lists are conducive to lock-free or low-lock implementations. (This is because inserting a node into a linked list requires updating just a couple of references, while inserting an element into a List-like structure may require moving thousands of existing elements.)

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

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

发布评论

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

评论(5

惯饮孤独 2024-10-29 01:47:30

如果不了解更多关于你在锁内所做的事情,那就不可能说。

例如,如果您所有的字典访问看起来像这样:

lock(lockObject)
{
    foo = dict[key];
}

... // elsewhere

lock(lockObject)
{
    dict[key] = foo;
}

那么您可以将其切换出去(尽管您可能不会看到性能有任何差异,所以如果它没有损坏,就不要修复它)。但是,如果您在与字典交互的锁定块中执行任何奇特的操作,那么您必须确保字典提供一个单个函数来完成您正在做的事情锁块内,否则您最终会得到功能上与以前不同的代码。最需要记住的是,字典仅保证对字典的并发调用以串行方式执行;它无法处理代码中的单个操作与字典多次交互的情况。类似的情况,当 ConcurrentDictionary 未考虑时,需要您自己的并发控制。

值得庆幸的是,ConcurrentDictionary 为更常见的多步骤操作(例如 AddOrUpdateGetOrAdd)提供了一些辅助函数,但它们无法涵盖所有​​情况。如果您发现自己必须努力将逻辑硬塞到这些函数中,那么最好处理您自己的并发性。

Without knowing more about what you're doing within the lock, then it's impossible to say.

For instance, if all of your dictionary access looks like this:

lock(lockObject)
{
    foo = dict[key];
}

... // elsewhere

lock(lockObject)
{
    dict[key] = foo;
}

Then you'll be fine switching it out (though you likely won't see any difference in performance, so if it ain't broke, don't fix it). However, if you're doing anything fancy within the lock block where you interact with the dictionary, then you'll have to make sure that the dictionary provides a single function that can accomplish what you're doing within the lock block, otherwise you'll end up with code that is functionally different from what you had before. The biggest thing to remember is that the dictionary only guarantees that concurrent calls to the dictionary are executed in a serial fashion; it can't handle cases where you have a single action in your code that interacts with the dictionary multiple times. Cases like that, when not accounted for by the ConcurrentDictionary, require your own concurrency control.

Thankfully, the ConcurrentDictionary provides some helper functions for more common multi-step operations like AddOrUpdate or GetOrAdd, but they can't cover every circumstance. If you find yourself having to work to shoehorn your logic into these functions, it may be better to handle your own concurrency.

行雁书 2024-10-29 01:47:30

这并不像用 ConcurrentDictionary 替换 Dictionary 那么简单,您需要调整代码,因为这些类具有行为不同的新方法,以保证线程安全。

例如,您不必调用 AddRemove,而是调用 TryAddTryRemove。使用这些以原子方式运行的方法非常重要,就好像您进行了两次调用,其中第二次调用依赖于第一次的结果,您仍然会遇到竞争条件并需要

It's not as simple as replacing Dictionary with ConcurrentDictionary, you'll need to adapt your code, as these classes have new methods that behave differently, in order to guarantee thread-safety.

Eg., instead of calling Add or Remove, you have TryAdd and TryRemove. It's important you use these methods that behave atomically, as if you make two calls where the second is reliant on the outcome of the first, you'll still have race conditions and need a lock.

七颜 2024-10-29 01:47:30

您可以将 Dictionary 替换为 ConcurrentDictionary

不过,对性能的影响可能不是您想要的(如果存在大量锁定/同步,性能可能会受到影响......但至少您的集合是线程安全的)。

You can replace Dictionary<TKey, TValue> with ConcurrentDictionary<TKey, TValue>.

The effect on performance may not be what you want though (if there is a lot of locking/synchronization, performance may suffer...but at least your collection is thread-safe).

一杆小烟枪 2024-10-29 01:47:30

虽然我不确定替换困难,但如果您需要在同一个“锁定会话”中访问字典中的多个元素,那么您需要修改代码。

如果 Microsoft 为读取和写入提供单独的锁,则可以提高性能,因为读取操作不应阻止其他读取操作。

While I'm unsure about replacement difficulties, but if you have anywhere where you need to access multiple elements in the dictionary in the same "lock session" then you'll need to modify your code.

It could give improved performance if Microsoft has given separate locks for read and write, since read operations shouldn't block other read operations.

黎夕旧梦 2024-10-29 01:47:30

是的,您可以安全地替换,但是为 plinq 设计的字典可能有一些额外的代码,用于添加您可能不会使用的功能。但性能开销会非常小。

Yes you can safely replace, however dictionary designed for plinq may have some extra code for added functionality that you may not use. But the performance overhead will be marginally very small.

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