Intro
C# 執行緒同步or鎖定作業的方式System.Threading.Monitor這邊稱為鎖定並不是keyword, 只是相較等候的方式, 這裡的行為比較像鎖定
另一種方法是等候作業 C# Thread 等候其它作業
Content
一般用法, 鎖定一個物件, 避免搶資源, 與 lock(obj)相同? 以下程式表示, 同時間, 只有一個thread可以在Enter與Exit之間
static void Main(string[] args) { object obj = new Object(); var thd1 = new Thread(delegate() { Console.WriteLine("Start thd1"); try { Monitor.Enter(obj); Console.WriteLine("enter thd1"); Thread.Sleep(1000); } finally { Monitor.Exit(obj); Console.WriteLine("thd1 exit"); } Console.WriteLine("End thd1"); }); var thd2 = new Thread(delegate() { Console.WriteLine("Start thd2"); try { Monitor.Enter(obj); Console.WriteLine("enter thd2"); Thread.Sleep(1000); } finally { Monitor.Exit(obj); Console.WriteLine("thd2 exit"); } Console.WriteLine("End thd2"); }); thd1.Start(); thd2.Start(); Console.ReadKey(); }
用法2: 暫時讓出鎖定物件, 用等待(wait)和喚醒(pulse)的方式
static void Main(string[] args) { object obj = new Object(); var thd1 = new Thread(delegate() { Console.WriteLine("thd1 Start"); lock (obj) //step2. thd1 勢必先取得 obj-lock { Monitor.Wait(obj); // step3. 但它把obj-lock讓出去, 並進入wait-staus Console.WriteLine("thd1 1st"); Monitor.Pulse(obj); // step7. 叫醒等待中的thd2 Monitor.Wait(obj); // step8. 把obj-lock讓出去, 並進入 wait-staus Console.WriteLine("thd1 2nd"); Monitor.Pulse(obj); // step11. 叫醒等待中的thd2 Monitor.Wait(obj); // step12. 把obj-lock讓出去, 並進入 wait-staus Console.WriteLine("thd1 3rd"); Monitor.Pulse(obj); // step14. 叫醒等待中的thread } Console.WriteLine("thd1 End"); }); var thd2 = new Thread(delegate() { Console.WriteLine("thd2 Start"); Thread.Sleep(1000); //step1. 讓thd2比較慢進入lock處理 lock (obj) // step4. thd2 取得 thd1 第一次讓出的obj-lock { Console.WriteLine("thd2 1st"); Monitor.Pulse(obj); // step5. 進入等待前把其它thread(thd1)叫起來, 通知它們進入runing狀態 //這邊註解的話有可能造成死鎖, 因為 thd1 進入 wait-staus, 而 thd2 在下一行即將進入wait-staus //在thd1下次取消執行權時就會往下跑 Monitor.Wait(obj); //step6. 把obj-lock讓出去, 並進入 wait-staus Console.WriteLine("thd2 2nd"); Monitor.Pulse(obj); // step9. 叫醒等待中的thd1 Monitor.Wait(obj); // step10. 把obj-lock讓出去, 並進入 wait-staus Console.WriteLine("thd2 3rd"); Monitor.Pulse(obj); // step13. 叫醒等待中的thd1 } Console.WriteLine("thd2 End"); }); thd1.Start(); thd2.Start(); Console.ReadKey(); }
沒有留言:
張貼留言