標籤:
ReaderWriterLock類
通常來講,一個類型的執行個體對於並行的讀操作是安全執行緒的,但是並行地根性操作則不是(並行地讀和更新也不是)。 這對於資源也是一樣的,比如一個檔案。當保護類型的執行個體安全時,使用一個簡單的排它鎖即解決問題,但是當有很多的讀操作而偶然的更新操作這就很不合理的限制了並發。一個例子就是這在一個業務程式伺服器中,為了快速尋找把資料緩衝到靜態欄位中。 在這個方案中,ReaderWriterLock類被設計成提供最大容量的鎖定。
ReaderWriterLock為讀和寫的鎖提供了不同的方法——AcquireReaderLock和AcquireWriterLock。兩個方法都需要一個逾時參數,並且在逾時發生後拋出ApplicationException異常(不同於大多數線程類的返回false等效的方法)。逾時發生相當容易在資源爭用嚴重的時候。
調用 ReleaseReaderLock或ReleaseWriterLock釋放鎖。 這些方法支援嵌套鎖,ReleaseLock方法也支援一次清除所有嵌套層級的鎖。(你可以隨後調用RestoreLock類重新鎖定相同的層級,它在ReleaseLock之前執行——如此來模仿Monitor.Wait的鎖定切換行為)。
你可以調用AcquireReaderLock開始一個read-lock ,然後通過UpgradeToWriterLock把它升級為write-lock。這個方法返回一個可能被用於調用DowngradeFromWriterLock的資訊。這個方式允許讀程式臨時地請求寫訪問同時不必必須在降級之後重新排隊列。
在接下來的這個例子中,4個線程被啟動:一個不停地往列表中增加項目;另一個不停地從列表中移除項目;其它兩個不停地報告列表中項目的個數。前兩者獲得寫的鎖,後兩者獲得讀的鎖。每個鎖的逾時參數為10秒。(異常處理一般要使用來捕捉ApplicationException,這個例子中出於方便而省略了).
例子:
class Program { static ReaderWriterLock rw = new ReaderWriterLock (); static List <int> items = new List <int> (); static Random rand = new Random (); static void Main (string[] args) { new Thread (delegate() { while (true) AppendItem(); } ).Start(); new Thread (delegate() { while (true) RemoveItem(); } ).Start(); new Thread (delegate() { while (true) WriteTotal(); } ).Start(); new Thread (delegate() { while (true) WriteTotal(); } ).Start(); } static int GetRandNum (int max) { lock (rand) return rand.Next (max); } static void WriteTotal() { rw.AcquireReaderLock (10000); int tot = 0; foreach (int i in items) tot += i; Console.WriteLine (tot); rw.ReleaseReaderLock(); } static void AppendItem () { rw.AcquireWriterLock (10000); items.Add (GetRandNum (1000)); Thread.SpinWait (400); rw.ReleaseWriterLock(); } static void RemoveItem () { rw.AcquireWriterLock (10000); if (items.Count > 0) items.RemoveAt (GetRandNum (items.Count)); rw.ReleaseWriterLock(); }}
往List中加項目要比移除快一些,這個例子在AppendItem中包含了SpinWait來保持項目總數平衡。
按照請求到達的順序,一共有四種 :
Reader-Reader,第二個不需等待,直接獲得讀控制權;
Reader-Writer,第二個需要等待第一個調用ReleaseReaderLock()釋放讀控制權後,才能獲得寫控制權;
Writer-Writer,第二個需要等待第一個調用ReleaseWriterLock()釋放寫控制權後,才能獲得寫控制權;
Writer-Reader,第二個需要等待第一個調用ReleaseWriterLock()釋放寫控制權後,才能獲得讀控制權。
原文連結:http://www.cnblogs.com/coderzh/articles/1586268.html
【轉】【Thread】ReaderWriterLock 讀寫鎖