让我们从代码开始;
checkedUnlock
是一个HashSet<ulong>
_hashsetLock
是一个对象
lock (_hashsetLock)
newMap = checkedUnlock.Add(uniqueId);
对比
fun
在一个整数
SpinWait.SpinUntil(() => Interlocked.CompareExchange(ref fun, 1, 0) == 1);
newMap = checkedUnlock.Add(uniqueId);
fun = 0;
我的理解是,SpinWait
在这种情况下应该像 一样工作,lock()
但是添加了更多的项目HashSet
,有时它匹配锁,有时其中还有 1 到 5 个项目,这很明显它不起作用
我的理解有缺陷吗?
编辑
我试过了,它似乎有效,我的测试显示与目前相同的lock()
数字
SpinWait spin = new SpinWait();
while (Interlocked.CompareExchange(ref fun, 1, 0) == 1)
spin.SpinOnce();
那么为什么它会与这个一起工作但不是 SpinWait.SpinUntil()
呢?
编辑#2
小全应用看
在这段代码中,SpinWait.SpinUntil
有时会爆炸(添加会抛出异常)但是当它工作时,计数会不同,所以我对此的预期行为是错误的
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
var list = new List<int>();
var rnd = new Random(42);
for (var i = 0; i < 1000000; ++i)
list.Add(rnd.Next(500000));
object _lock1 = new object();
var hashset1 = new HashSet<int>();
int _lock2 = 0;
var hashset2 = new HashSet<int>();
int _lock3 = 0;
var hashset3 = new HashSet<int>();
Parallel.ForEach(list, item =>
{
/******************/
lock (_lock1)
hashset1.Add(item);
/******************/
/******************/
SpinWait.SpinUntil(() => Interlocked.CompareExchange(ref _lock2, 1, 0) == 1);
hashset2.Add(item);
_lock2 = 0;
/******************/
/******************/
SpinWait spin = new SpinWait();
while (Interlocked.CompareExchange(ref _lock3, 1, 0) == 1)
spin.SpinOnce();
hashset3.Add(item);
_lock3 = 0;
/******************/
});
Console.WriteLine("Lock: {0}", hashset1.Count);
Console.WriteLine("SpinWaitUntil: {0}", hashset2.Count);
Console.WriteLine("SpinWait: {0}", hashset3.Count);
Console.ReadKey();
}
}
}