Interlocked:为多个线程共享的变量提供原子操作。
Interlocked.Increment(ref value) | 数值加一(原子性操作) |
Interlocked.Decrement(ref value) | 数值减一(原子性操作) |
Interlocked.Exchange(ref value1, value2) | 交换:把值2赋给值1;返回原值 |
Interlocked.CompareExchange(ref value1, value2, value3) | 实现比较和交换两种功能:值1和值3比较,如果相同,把值2给值1,不相同则不作任何操作;返回原值(多用于判断条件)(示例3中会用到) |
- 实现原子级运算
1 int increament = 0; 2 Thread th1 = new Thread(() => 3 { 4 for (int i = 0; i < 10; i++) 5 Console.WriteLine($"th1 {Interlocked.Increment(ref increament)}"); 6 }); 7 8 Thread th2 = new Thread(() => 9 { 10 for (int i = 0; i < 10; i++) 11 Console.WriteLine($"th2 {Interlocked.Increment(ref increament)}"); 12 }); 13 14 Thread th3 = new Thread(() => 15 { 16 for (int i = 0; i < 10; i++) 17 Console.WriteLine($"th3 {Interlocked.Increment(ref increament)}"); 18 }); 19 20 Thread th4 = new Thread(() => 21 { 22 for (int i = 0; i < 10; i++) 23 Console.WriteLine($"th4 {Interlocked.Increment(ref increament)}"); 24 }); 25 26 th1.Start(); 27 th2.Start(); 28 th3.Start(); 29 th4.Start(); 30 Console.ReadKey();
运行结果:
1 int increament = 0; 2 Thread th1 = new Thread(() => 3 { 4 for (int i = 0; i < 10; i++) 5 //Console.WriteLine($"th1 {Interlocked.Increment(ref increament)}"); 6 Console.WriteLine($"th1 {increament++}"); 7 }); 8 9 Thread th2 = new Thread(() => 10 { 11 for (int i = 0; i < 10; i++) 12 //Console.WriteLine($"th2 {Interlocked.Increment(ref increament)}"); 13 Console.WriteLine($"th2 {increament++}"); 14 }); 15 16 Thread th3 = new Thread(() => 17 { 18 for (int i = 0; i < 10; i++) 19 //Console.WriteLine($"th3 {Interlocked.Increment(ref increament)}"); 20 Console.WriteLine($"th3 {increament++}"); 21 }); 22 23 Thread th4 = new Thread(() => 24 { 25 for (int i = 0; i < 10; i++) 26 //Console.WriteLine($"th4 {Interlocked.Increment(ref increament)}"); 27 Console.WriteLine($"th4 {increament++}"); 28 }); 29 30 th1.Start(); 31 th2.Start(); 32 th3.Start(); 33 th4.Start(); 34 Console.ReadKey();
- 模拟锁
用Exchange函数实现锁
1 //0 for false, 1 for true. 2 private static int usingResource = 0; 3 //A simple method that denies reentrancy. 4 static bool UseResource() 5 { 6 //0 indicates that the method is not in use. 7 if (0 == Interlocked.Exchange(ref usingResource, 1)) 8 { 9 Console.WriteLine("{0} acquired the lock", Thread.CurrentThread.Name); 10 11 //Code to access a resource that is not thread safe would go here. 12 13 //Simulate some work 14 Thread.Sleep(500); 15 16 Console.WriteLine("{0} exiting lock", Thread.CurrentThread.Name); 17 18 //Release the lock 19 Interlocked.Exchange(ref usingResource, 0); 20 return true; 21 } 22 else 23 { 24 Console.WriteLine(" {0} was denied the lock", Thread.CurrentThread.Name); 25 return false; 26 } 27 }
用CompareExchange函数实现锁
1 private double totalValue = 0.0; 2 3 public double Total { get { return totalValue; } } 4 5 public double AddToTotal(double addend) 6 { 7 double initialValue, computedValue; 8 do 9 { 10 initialValue = totalValue;//---(1) 11 computedValue = initialValue + addend;//---(2) 12 13 } 14 while (initialValue != Interlocked.CompareExchange(ref totalValue, 15 computedValue, initialValue)); 16 //Interlocked.CompareExchange:比较totalValue与initialValue是否相同,如果相同,则用computedValue的值覆盖totalValue 17 18 //如果totalValue与initialValue值不相同,则说明在(1)与(2)步骤执行的同时, 19 //其他线程执行了对totalValue进行了改变 20 return computedValue; 21 }