相关疑难解决方法(0)

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

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

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.");
Run Code Online (Sandbox Code Playgroud)

而不是传统的lock:

lock(lockObject)
{
    // PROCESS SOMETHING HERE
}
Run Code Online (Sandbox Code Playgroud)

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

PS:我知道有ConcurrentDictionary一些最新版本的.NET,但我不能用于遗留项目.

编辑:

在我的具体情况下,我正在做的只是Dictionary以一种线程安全的方式操作内部类.

例:

public bool RemoveItem(TKey key)
{
    // open lock
    var current = Thread.CurrentThread.ManagedThreadId;
    while (Interlocked.CompareExchange(ref owner, current, 0) != current) { …
Run Code Online (Sandbox Code Playgroud)

.net c# multithreading interlocked thread-safety

6
推荐指数
4
解决办法
4449
查看次数

Interlocked.Increment vs lock in debug vs release mode

我正在测试我的计算机架构上的行为Interlocked.Incrementlock行为,因为我阅读了本文中的以下几行。

正如用 Interlocked.Increment 重写的那样,该方法应该执行得更快,至少在某些架构上是这样。

使用以下代码,我确信在我的项目中检查锁是值得的。

var watch = new Stopwatch();
var locker = new object();
int counter = 0;

watch.Start();
for (int i = 0; i < 100000000; i++)
{
    lock (locker)
    {
        counter++;
    }
}
watch.Stop();
Console.WriteLine(watch.Elapsed.TotalSeconds);

watch.Reset();
counter = 0;

watch.Start();
for (int i = 0; i < 100000000; i++)
{
    Interlocked.Increment(ref counter);
}
watch.Stop();
Console.WriteLine(watch.Elapsed.TotalSeconds);
Run Code Online (Sandbox Code Playgroud)

我越来越有近似值稳定的结果2.4S用于锁定和1.2秒的互锁。然而,我惊讶地发现在发布模式下运行此代码仅将 Interlocked 的值提高到大约0.7 秒,并且锁定时间保持不变。这是为什么?在释放模式下锁定不是互锁时如何优化互锁?

c# locking interlocked release-mode debug-mode

3
推荐指数
1
解决办法
448
查看次数