例1、不用線程鎖的情況下,兩個線程對同一個變量進行加減操作
static void Main(string[] args) { Counter counter = new Counter(); var t1 = new Thread(() => TestCounter(counter)); var t2 = new Thread(() => TestCounter(counter)); t1.Start(); t2.Start(); Thread.Sleep(TimeSpan.FromSeconds(3));//睡眠3秒,保證t1、t2兩個線程都運行完畢 Console.WriteLine(counter.count); Console.Read(); }
對count變量不斷地加1減1,最后count應該為0,但可以看出用兩個線程來進行這個操作的時候,往往得到的結果並不是0,出現錯誤。
例2、使用線程鎖,兩個線程對同一個變量進行加減操作
static void Main(string[] args) { CounterWithLock counterlock = new CounterWithLock(); var t1 = new Thread(() => TestCounter(counterlock)); var t2 = new Thread(() => TestCounter(counterlock)); t1.Start(); t2.Start(); Thread.Sleep(TimeSpan.FromSeconds(3));//睡眠3秒,保證t1、t2兩個線程都運行完畢 Console.WriteLine(counterlock.count); Console.Read(); }
加上線程鎖后,結果正常,因此加上線程鎖才能保證不會出錯。
例1、例2所用到的類和方法
/// <summary> /// 對同一個變量進行1000次加減操作 /// </summary> /// <param name="c"></param> static void TestCounter(CounterBase c) { Console.WriteLine("TestCounter start"); for (int i = 0; i < 1000; i++) { c.Increment(); c.Decrement(); } Console.WriteLine("TestCounter end"); }
abstract class CounterBase { public abstract void Increment(); public abstract void Decrement(); } /// <summary> /// 沒有鎖 /// </summary> class Counter : CounterBase { public int count { get; private set; } public override void Increment() { count ++; } public override void Decrement() { count --; } } /// <summary> /// 加鎖 /// </summary> class CounterWithLock : CounterBase { private readonly object locker = new object(); public int count { get; private set; } public override void Increment() { lock (locker) { count++; } } public override void Decrement() { lock (locker) { count--; } } }