所谓原子操作是指不会被线程调度机制打断的操作;这种操作一旦开始,就一直运行到结束,中间不会有任何 context switch (切换到另一个线程)。
原子操作案例
//Interlocked为原子操作相关类,a值为最终值,b可能因为同时操作返回不同的值 public static class AtomicSaple { public static int a = 0; public static void Sample() { var b = 0; b = Interlocked.Increment(ref a); Console.WriteLine(b); b = Interlocked.Decrement(ref a); Console.WriteLine(b); b = Interlocked.Add(ref a, 2); Console.WriteLine(b); //a的值改变为1 Interlocked.Exchange(ref a, 1); //如果a=0返回1 Interlocked.CompareExchange(ref a,1,0); } }原子操作实现无锁算法
public class Counter { public int TimesA { get; set; } public int TimesB { get; set; } public Counter(int timesA, int timesB) { TimesA = timesA; TimesB = timesB; } } public static class CounterSample { public static Counter Counter1 = new Counter(0, 0); /// <summary> /// 递增计数器,返回递增后的值 /// </summary> /// <param name="counter"></param> /// <returns></returns> public static Counter Increment(ref Counter counter) { Counter oldCounter, newCounter; do { oldCounter = counter; newCounter = new Counter(oldCounter.TimesA + 1, oldCounter.TimesB + 1); // 使用循环确保成功 } while (Interlocked.CompareExchange(ref counter, newCounter,oldCounter) != oldCounter); return newCounter; } public static void IncrementCounter() { var result = Increment(ref Counter1); Console.WriteLine($"TimesA={result.TimesA},TimesB={result.TimesB}"); } public static void ThreadIncrement() { var thread1 = new Thread(IncrementCounter); var thread2 = new Thread(IncrementCounter); thread1.Start(); thread2.Start(); } public static void PrintCounter() { var c = Counter1; Console.WriteLine($"Counter={c.TimesA},{c.TimesB}"); } public static void Run() { ThreadIncrement(); Thread.Sleep(1000); PrintCounter(); } }