C# lock 防止多執行續同時共用資源

先來看一段程式碼:
    
    static void Main(string[] args)
    {

        Task task1 = Task.Run(() => IncrementSharedResource());
        Task task2 = Task.Run(() => IncrementSharedResource());

        Task.WaitAll(task1, task2);

        Console.WriteLine("Final shared resource value: " + _sharedResource);
    }
    
    private static int _sharedResource = 0;

    static void IncrementSharedResource()
    {
        for (int i = 0; i < 100_000; i++)
        {
            _sharedResource++;
        }
    }
    

上面的程式碼執行結果範例是 110,316 ,並不是 200,000。原因是會先取得 _sharedResource 變數的內容,將其加一後寫回 _sharedResource 變數中。假設現在是 1 ,兩個人同時把他 +1 ,想要將 2 寫回變數中,確實成功了,但是如果一一執行會 +2 ,但是兩個執行緒同時做這件事情,所以實際上只有 +1 。

在 C# 中要解決這件事情很簡單只要使用 lock 區塊就可以完美解決,會限制 lock 區塊中同時只會有一個執行緒在處理:
    
    static void Main(string[] args)
    {
        Task task1 = Task.Run(() => IncrementSharedResource());
        Task task2 = Task.Run(() => IncrementSharedResource());

        Task.WaitAll(task1, task2);

        Console.WriteLine("Final shared resource value: " + _sharedResource);
    }

    private static readonly object LockObject = new object();
    private static int _sharedResource = 0;

    static void IncrementSharedResource()
    {
        for (int i = 0; i < 100_000; i++)
        {
            lock (LockObject)
            {
                _sharedResource++;
            }
        }
    }
    



參考資料:
Microsoft.Learn - lock 陳述式

留言

張貼留言

如果有任何問題、建議、想說的話或文章題目推薦,都歡迎留言或來信: a@ruyut.com