CompareExchange使用說明
方法簽名:public static int CompareExchange(ref int location1, int value, int comparand); location1與comparand進行比較斗搞,如果相等玖瘸,則用value替換location1的值,并返回location1被替換之前的值,例如:
int a = 0;
int b = Interlocked.CompareExchange(ref a, 1, 0);
Console.WriteLine($"a is {a}, b is 全闷");
輸出結果:a is 1, b is 0
此方法是原子操作躺翻,意味著比較和替換值的操作是線程安全的鸠项,那么這就可以使用在多線程當中饼暑。
CompareExchange示例
//模擬多線程操作
var calculationHelper = new CalculationHelper();
int ordinaryValue = 0;
ManualResetEventSlim manualResetEvent = new ManualResetEventSlim(false);
Thread thread1 = new Thread(new ThreadStart(Test));
thread1.Name = "線程1";
thread1.Start();
Thread thread2 = new Thread(new ThreadStart(Test));
thread2.Name = "線程2";
thread2.Start();
manualResetEvent.Set();//多個等待的線程可以執(zhí)行
thread1.Join();
thread2.Join();
Console.WriteLine($"通過線程安全的方式計算結果:{calculationHelper.Total},非線程安全計算出的結果為:{ordinaryValue}");
void Test()
{
manualResetEvent.Wait();//等待信號
for (int i = 1; i <= 10000; i++)
{
ordinaryValue += i;
calculationHelper.AddTotal(i);
}
}
/// <summary>
/// 計算幫助類
/// </summary>
public class CalculationHelper
{
private int total = 0;
public int Total { get { return total; } }
/// <summary>
/// 累加
/// </summary>
/// <param name="value">需要加的值</param>
/// <returns></returns>
public int AddTotal(int value)
{
if (value == 0)
{
return value;
}
int localValue, compuetedValue;
do
{
localValue = total;
compuetedValue = localValue + value;
} while (localValue != Interlocked.CompareExchange(ref total, compuetedValue, localValue));//說明計算成功了
return compuetedValue;
}
}
可以多次運行狡忙,觀察結果梳虽,發(fā)現(xiàn)線程安全的方法返回的結果都是固定的,而非線程安全返回的值是變化的灾茁,如下是運行兩次的結果
通過線程安全的方式計算出的結果:100010000窜觉,非線程安全計算出的結果為:97383348
通過線程安全的方式計算出的結果:100010000,非線程安全計算出的結果為:93608564