【C#】為什么有可能會被多個線程修改的對象要加線程鎖


例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--;
        }
    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM