c# - Interlocked.CompareExchange 真的比简单的锁更快吗?

标签 c# .net multithreading thread-safety interlocked

我遇到了 .NET 3.5 的 ConcurrentDictionary 实现(很抱歉我现在可以找到链接),它使用这种锁定方法:

var current = Thread.CurrentThread.ManagedThreadId;
while (Interlocked.CompareExchange(ref owner, current, 0) != current) { }

// PROCESS SOMETHING HERE

if (current != Interlocked.Exchange(ref owner, 0))
        throw new UnauthorizedAccessException("Thread had access to cache even though it shouldn't have.");

代替传统的lock:

lock(lockObject)
{
    // PROCESS SOMETHING HERE
}

问题是:这样做有什么真正的理由吗?它是更快还是有一些隐藏的好处?

PS:我知道在某些最新版本的 .NET 中有一个 ConcurrentDictionary,但我不能将其用于遗留项目。

编辑:

在我的特定情况下,我所做的只是以线程安全的方式操作内部 Dictionary 类。

例子:

public bool RemoveItem(TKey key)
{
    // open lock
    var current = Thread.CurrentThread.ManagedThreadId;
    while (Interlocked.CompareExchange(ref owner, current, 0) != current) { }


    // real processing starts here (entries is a regular `Dictionary` class.
    var found = entries.Remove(key);


    // verify lock
    if (current != Interlocked.Exchange(ref owner, 0))
        throw new UnauthorizedAccessException("Thread had access to cache even though it shouldn't have.");
    return found;
}

正如@doctorlove 所建议的,这是代码:https://github.com/miensol/SimpleConfigSections/blob/master/SimpleConfigSections/Cache.cs

最佳答案

您的问题没有明确的答案。我会回答:视情况而定

您提供的代码的作用是:

  1. 等待对象处于已知状态(threadId == 0 == no current work)
  2. 工作
  3. 将已知状态设置回对象
  4. 现在另一个线程也可以工作了,因为它可以从第 1 步转到第 2 步

正如您所注意到的,代码中有一个循环实际执行“等待”步骤。 您不会阻塞线程,直到您可以访问您的关键部分,您只是消耗 CPU 而不是。尝试用 Thread.Sleep(2000) 替换您的处理(在您的情况下,调用 Remove),您会看到另一个“等待”线程消耗了所有你的一个 CPU 循环 2s。

也就是说,哪个更好取决于几个因素。例如:有多少个并发访问?手术需要多长时间才能完成?你有多少个 CPU?

我会使用 lock 而不是 Interlocked 因为它更容易阅读和维护。异常(exception)情况是您有一段代码被调用了数百万次,并且您确定 Interlocked 更快的特定用例。

因此您必须自己衡量这两种方法。如果您没有时间这样做,那么您可能不需要担心性能问题,您应该使用 lock

关于c# - Interlocked.CompareExchange 真的比简单的锁更快吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20800954/

相关文章:

c# - 通过 UI 自动化清除 RichTextBox 文本?

c++ - 如何从 win32 进程获取线程句柄列表?

c# - MVC Razor 柱模型为空

c# - 如何使用 C# 编辑网站中的文本字段?

.net - 如何在网页上实现文件上传进度条?

c# - 从 C# 应用程序向服务器发送 Json 格式消息

java - 我的 Produce Consumer 挂起

c# - 多线程问题更新值

C# 泛型 : Can you convert <T> ToString?

c# - WPF - 如何绑定(bind) DataGridTemplateColumn