第十三節:實際開發中使用最多的監視鎖Monitor、lock語法糖的擴展、混合鎖的使用(ManualResetEvent、SemaphoreSlim、ReaderWriterLockSlim)

一. 監視鎖(Monitor和lock)函數

1. Monitor類,限定線程個數的一把鎖,兩個核心方法:性能

  Enter:鎖住某個資源。測試

  Exit:退出某一個資源。spa

測試案例:開啓5個線程同時對一個變量進行自增操做,結果變量有序的輸出,說明該鎖同時只容許一個線程訪問。線程

可是寫法很麻煩,每次都要try-catch-finally,還要聲明bool變量。這個時候lock語法糖就很好的解決了這個問題。3d

 代碼實踐:code

 1 static object lockMe = new object();
 2         {
 3                 for (int i = 0; i < 5; i++)
 4                 {
 5                     Task.Factory.StartNew(() =>
 6                     {
 7                         for (int j = 0; j < 100; j++)
 8                         {
 9                             var b = false;
10                             try
11                             {
12                                 Monitor.Enter(lockMe, ref b);
13                                 Console.WriteLine(num++);
14                             }
15                             catch (Exception)
16                             {
17 
18                                 throw;
19                             }
20                             finally
21                             {
22                                 if (b)
23                                 {
24                                     Monitor.Exit(lockMe);
25                                 }
26                             }
27 
28                         }
29 
30                     });
31                 }
32             }     

2. lock語法糖 blog

  使用很簡單,聲明一個靜態的object類型變量,調用lock語法糖,將共享變量放入其中,便可保證lock內同時只能一個線程訪問。資源

 代碼實踐:it

 1             {
 2                 for (int i = 0; i < 5; i++)
 3                 {
 4                     Task.Factory.StartNew(() =>
 5                     {
 6                         for (int j = 0; j < 100; j++)
 7                         {
 8                             lock (lockMe)
 9                             {
10                                 Console.WriteLine(num++);
11                             }
12                         }
13                     });
14                 }
15             }

 

二. 混合鎖

1. 簡介:混合鎖=用戶模式鎖+內核模式鎖,先在用戶模式下內旋,若是超過必定的閾值,會切換到內核鎖,在內旋模式下,咱們會看到大量的Sleep(0),Sleep(1),Yield等語法。

  Thread.Sleep(1) 讓線程休眠1ms

  Thread.Sleep(0) 讓線程放棄當前的時間片,讓本線程更高或者同等線程獲得時間片運行。

  Thread.Yield() 讓線程當即放棄當前的時間片,能夠讓更低級別的線程獲得運行,當其餘thread時間片用完,本thread再度喚醒。

 混合鎖包括如下三種:ManualResetEventSlim、SemaphoreSlim、ReaderWriterLockSlim,這三種混合鎖,要比他們對應的內核模式鎖 (ManualResetEvent、Semaphore、ReaderWriterLock),的性能高的多。

2. ManualResetEventSlim

  構造函數默認爲false,能夠使用Wait方法替代WaitOne方法,支持任務取消. (詳細的代碼同內核版本相似,這裏不作測試了)

3. SemaphoreSlim

  用法和內核版本相似,使用Wait方法代替WaitOne方法,Release方法不變。(詳細的代碼同內核版本相似,這裏不作測試了)

4. ReaderWriterLockSlim

  用法和內核版本相似,可是四個核心方法換成了:

  鎖讀的兩個核心方法:EnterReadLock、ExitReadLock。

  鎖寫的兩個核心方法:EnterWriteLock、ExitWriteLock。

  (詳細的代碼同內核版本相似,這裏不作測試了)

 

 

 

 

相關文章
相關標籤/搜索