在C#中,赋值和简单的数字运算都不是原子型操作。在多线程环境下,会产生数据安全的问题。
在多线程环境下,我们可以通过使用System.Threading.Interlocked类来实现原子型操作当个数据,使用它比使用Monitor类跟简单。
Interlocked类主要方法
方法 | 作用 |
CompareExchange() | 安全比较两个值是不是相等。如果相等,将第三个值于其中一个值交换 |
Decrement() | 安全递减1,相当于 i-- |
Exchange() | 安全交换数据,相当于 a = 30 |
Increment() | 安全递加1,相当于 i++ |
Add() | 安全相加一个数值,相当于 a = a + 3 |
Read() | 安全读取数值,相等于int a=b |
例子1:
private int value1 = 0; public void TestIncrementUnSafe() { for (int i = 0; i < 5; i++) { Thread t = new Thread(IncrementValue1); t.Name = "t1 " + i; t.Start(); } Thread.Sleep(2000); //value maybe 500000 Console.WriteLine("value1 = " + value1); } private int value2 = 0; public void TestIncrementSafe() { for (int i = 0; i < 5; i++) { Thread t = new Thread(IncrementValue2); t.Name = "t2 " + i; t.Start(); } Thread.Sleep(2000); //value should be 500000 Console.WriteLine("value2 = " + value2); } private void IncrementValue1() { for (int i = 0; i < 1000000; i++) { value1++; //Console.WriteLine(Thread.CurrentThread.Name); } } private void IncrementValue2() { for (int i = 0; i < 1000000; i++) { Interlocked.Increment(ref value2); } }
控制台输出:
运行结果1
value1 = 4612592
value2 = 5000000
运行结果2
value1 = 4697979
value2 = 5000000
例子2
private int value3 = 0; public void TestExchangeSafe() { for (int i = 0; i < 5; i++) { Thread t = new Thread(ExchangeValue3); t.Name = "t2 " + i; t.Start(); } Thread.Sleep(2000); //value should be 83 Console.WriteLine("value3 = " + value3); } private void ExchangeValue3() { Interlocked.Exchange(ref value3, 83); } private int value4 = 0; public void TestCompareExchangeSafe() { for (int i = 0; i < 5; i++) { Thread t = new Thread(ExchangeValue3); t.Name = "t2 " + i; t.Start(); } Thread.Sleep(2000); //value should be 99 or 0 Console.WriteLine("value4 = " + value4); } private void ExchangeValue4() { //if value4=0, set value4=99 Interlocked.CompareExchange(ref value4, 99,0); }
控制台输出:
value4 = 0
value3 = 83
转载于:https://blog.51cto.com/13713878410/1530358