我遇到了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) 我正在测试我的计算机架构上的行为Interlocked.Increment和lock行为,因为我阅读了本文中的以下几行。
正如用 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 秒,并且锁定时间保持不变。这是为什么?在释放模式下锁定不是互锁时如何优化互锁?