原子操作、自旋锁
private static int a = 0;
static void Main(string[] args)
{
// 原子操作
var b = 0;
b = Interlocked.Increment(ref a); // 自增1
b = Interlocked.Decrement(ref a);// 自减
b = Interlocked.Add(ref a, b); // 返回a 加b的值
Interlocked.Exchange(ref a, 1); // 返回交换后的值,
Interlocked.CompareExchange(ref a, 2, 0); // 变量a的值如果等于0,则将2 赋值给a ,并且然后返回原始值(修改之前的值)


自旋锁:
线程会不断的循环获取锁,直到锁被释放。 不公平的锁,没办法保证等待最长时间的线程获取锁,假如有8个线程,都在不断循环获取锁,总有线程‘’点子背‘’,获取不到锁(线程饥饿)
优点:自旋锁 不会使线程的状态切换,减小上下文的切换,上下文的切换 会消耗性能
public static class Sample
{
private static int _lock = 0;
private static int _CounterA = 0;
private static int _Counterb = 0;
private static SpinLock _locker = new SpinLock();
public static void IncrementCounter()
{
var spinwait = new SpinWait();
while (Interlocked.Exchange(ref _lock, 1) != 0)
{
// 汇编指令,pause
Thread.SpinWait(1);
// 或者
spinwait.SpinOnce();
// 一定次数内,核心数大于1。会调用 Thread.SpinWait
// 超过一定的次数,核心数等于1,会交替调用
// 【thread.sleep(0)[windows中的sleep函数,实际上调用sleepex的一个系统函数]和thread.yied[他是调用一个叫switchtothread的函数],
// 前者在整个核心中切换,后者只在自己核心切换,前者赋值0的意义是立刻放在待执行的队列里】
// 交替使用告诉操作系统切换到其他线程
//在超过一定的次数,thread.sleep(1) 会休眠1毫秒,减少性能消耗
}
//锁保护区
{
_CounterA++;
_Counterb++;
}
// 释放锁
Interlocked.Exchange(ref _lock, 0);
// 以下方式可替换上面,直接使用封装好的类,直接实现了自旋锁
{
var lockToken = false;
try
{
_locker.Enter(ref lockToken);
// 锁保护区
{
_CounterA++;
_Counterb++;
}
}
finally
{
// 释放锁
if (lockToken)
{
_locker.Exit();
}
}
}
}
}

浙公网安备 33010602011771号