c# 解決死鎖問題Monitor
阿新 • • 發佈:2020-07-02
前言
在高併發中,一個很關鍵的問題就是要避免死鎖。
那麼為什麼會產生死鎖呢?這種情況多見嗎?
舉一個例子:
比如方法一中先lock(object1),在lock(object1)中lock(object2)。
方法二種則相反。
那麼這時候可以看出,如果方法一中lock了object1,這時候請求object2。
方法二種lock了object2,這時候請求object1,那麼這時候就出現問題了。
這樣解釋不太明白,那麼直接看程式碼吧。
正文
看下這個吧:
static void Main(string[] args) { object lock1 = new object(); object lock2 = new object(); new Thread(() => LockTooMuch(lock1, lock2)).Start(); lock (lock2) { Thread.Sleep(1000); Console.WriteLine("try to get lock1"); if (Monitor.TryEnter(lock1, TimeSpan.FromSeconds(5))) { Console.WriteLine("Acquired a protected resource succesfully"); } else { Console.WriteLine("Time out a resource"); } } Console.Read(); } static void LockTooMuch(object lock1, object lock2) { lock (lock1) { Thread.Sleep(1000); lock (lock2) { Console.WriteLine("enter lock2"); }; } }
結果:
這個是怎麼執行的呢?
主執行緒獲取lock2,然後分支執行緒獲取lock1,然後請求lock2。
這時候就堵塞了,可以拿上面程式碼執行一下,會堵塞5秒。
這個5秒怎麼來的呢?if (Monitor.TryEnter(lock1, TimeSpan.FromSeconds(5))) 這時候是嘗試去獲取lock1,
因為lock1倍分支執行緒給獲取了,那麼獲取不到,這時候等待5秒,5秒後獲取不到就直接走了lese這條路,然後就釋放了lock2,這時候分支執行緒就繼續執行。