Home [C# 筆記] Threading - C# Basic Thread Synchronization (Lock)
Post
Cancel

[C# 筆記] Threading - C# Basic Thread Synchronization (Lock)

C# Basic Thread Synchronization

上一個範例可以看出,當主執行緒睡半秒啟動後,thread2 正在處理舊的數據,那麼該如何解決這個問題呢?讓它們可以同步一點呢?

可以想想賽跑時,會有接力棒,一個傳一個賽跑者…

我們可以宣告一個類似接力棒的變數baton,當執行緒進入危險區域時,它必須要有接力棒,
程式碼中,什麼是「危險區域」? 「危險區域」是當我有「讀」、「寫」,特別是對這些「共享數據」…

上一個範例中的「共享數據」,就是靜態變數 count

使用 Lock

解決執行緒同步搶資源的最基本同步的方法,就是使用lock

1
2
3
4
lock (x) 
{
    // Your code...
}

lock 陳述式- 同步處理執行緒對共用資源的存取

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
internal class Program
{
    static int count = 0; //變數是靜態static,代表執行緒共享同一塊記憶體
    static object baton = new object(); //接力棒

    static void Main(string[] args)
    {
        //建立兩個執行緒,讓它們都進入IncrementCount方法
        var thread1 = new Thread(IncrementCount);
        var thread2 = new Thread(IncrementCount);

        thread1.Start();
        Thread.Sleep(500); //讓主執行緒不同步半秒
        thread2.Start(); //當主執行緒睡半秒啟動後,thread2正在處理舊的數據
    }

    static void IncrementCount()
    {
        while (true)
        {
            //使用lock,在搶資源的同時,讓執行緒儘可能的同步
            lock (baton) 
            {
                int temp = count;
                Thread.Sleep(500); //讓主執行緒睡半秒
                count = temp + 1;

                //做一個有趣的輸出
                Console.WriteLine($"Thread ID: {Thread.CurrentThread.ManagedThreadId} incremented count to: {count}");
            }

            Thread.Sleep(1000); //讓執行緒睡眠1000毫秒(讓程式暫停一秒)
        }
    }
}

執行結果:

會發現控制台輸出的結果會變很慢,但是它的count 是井然有序的。

1
2
3
4
5
6
7
8
9
10
11
12
Thread ID: 10 incremented count to: 1
Thread ID: 11 incremented count to: 2
Thread ID: 10 incremented count to: 3
Thread ID: 11 incremented count to: 4
Thread ID: 10 incremented count to: 5
Thread ID: 11 incremented count to: 6
Thread ID: 10 incremented count to: 7
Thread ID: 11 incremented count to: 8
Thread ID: 10 incremented count to: 9
Thread ID: 11 incremented count to: 10
Thread ID: 10 incremented count to: 11
Thread ID: 11 incremented count to: 12

##

像買票:看電影、飛機票、車票…等,如果是特殊假日,一定會有很多人競爭這個門票、位置,
不會在已經進入結帳時,進行下一步,卻發生該票已經被買走了…
它背後有可能的機制,可能會為這張票保留個10分鐘,你可以成功購買這張票,如果你沒有買,票就會供其他人購買了。

在爭奪這個共享數據,我們需要進行一些協調,確保沒有兩個人同時購買到同一張票,

C# Basic Thread Synchronization

This post is licensed under CC BY 4.0 by the author.