Interlocked 实现自旋锁
/// <summary>
/// 自旋锁
/// </summary>
public class ASpinLock
{
public ASpinLock(int timeOut = 1000)
{
TimeOut = timeOut;
}
/// <summary>
/// 信号量
/// </summary>
public long Semaphore = 1;
/// <summary>
/// 最大等待资源时间
/// 单位:毫秒
/// </summary>
public int TimeOut { get; set; }
/// <summary>
/// 自旋锁
/// </summary>
public void Enter()
{
var now = DateTime.Now;
while (Interlocked.CompareExchange(ref Semaphore, 0, 1) != 1)
{
var timeDiff = DateTime.Now - now;
var totalMsDiff = timeDiff.TotalMilliseconds;
if (totalMsDiff > TimeOut)
{
throw new Exception($"锁超时!{totalMsDiff}");
}
}
}
/// <summary>
/// 释放锁
/// </summary>
public void Exit()
{
Interlocked.Exchange(ref Semaphore, 1);
}
}
Client:
static int Count = 0;
static void Main(string[] args)
{
Stopwatch sw = Stopwatch.StartNew();
ASpinLock aspinLock = new ASpinLock(150);
var tasks = new List<Task>();
try
{
for (var i = 0; i < 10; i++)
{
var task = Task.Run(() =>
{
Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
aspinLock.Enter();
Count = Count + 1;
Thread.Sleep(15);
aspinLock.Exit();
});
tasks.Add(task);
}
Task.WaitAll(tasks.ToArray());
}
catch (AggregateException aEx)
{
foreach (var ex in aEx.InnerExceptions)
{
Console.WriteLine($"Error:{ex.Message}");
}
}
Console.WriteLine($"Count: {Count} | TimeTaken:{sw.ElapsedMilliseconds}");
Console.ReadLine();
}
}