哈囉,大家好,今天是第三天 ~
之前有提到過多執行緒沒有適當使用時,可能會導致資料錯亂的問題,其實這可以透過 lock
關鍵字解決。
lock 關鍵字的使用,可以避免不同執行緒同時存取同一個資源,導致資源同時被存取而引發的錯誤。
private object key = new object();
private void work()
{
lock(key)
{
// 存取資源
}
}
key 可使用任何型別的物件,它只會單純的當作一個鑰匙被看待。當不同執行緒在執行到 lock 時,會先檢查 key 是否被占用,若被占用,則等待到 key 被釋放後再繼續執行。
[C#] 多執行緒(3) 互斥鎖 Mutex – Program – C.Y.C 提到的互斥鎖,藉由存取變數副本的方法,可以增加多執行緒程式的效能。
以下是結合 Day 14: C# 多工處理: Thread - iT 邦幫忙 內文範例,所改寫的程式碼:
public class Day3Lock{
int n;
object key = new object();
private void AddN(){ // 不斷對 n 變數相加
for(int i = 0;i < 500000;i++){
lock(key){ // 可以嘗試把 lock 拿掉,觀察執行速度和結果
n = n + 1;
}
}
}
public void Run(){
DateTime startTime = DateTime.Now;
Thread threadAdd = new Thread(AddN);
threadAdd.Start();
Thread threadAdd2 = new Thread(AddN);
threadAdd2.Start();
threadAdd.Join();
threadAdd2.Join();
Console.WriteLine(n.ToString()); // 輸出結果應該要是 1000000
Console.WriteLine(DateTime.Now - startTime); // 執行的時間
}
}
執行結果:
1000000 // 第一次
00:00:00.0461334
1000000 // 第二次
00:00:00.0443492
1000000 // 第三次
00:00:00.0368109
接下來把 lock
拿掉:
731671 // 第一次
00:00:00.0118885
720287 // 第二次
00:00:00.0117529
638615 // 第三次
00:00:00.0122623
發現速度會變快,但是計算結果就會出錯。