NET多線程同步方法詳解(三):讀寫鎖(ReadWriteLock)

讀寫鎖的出現主要是在很多情況下,我們讀資源的操作要多於寫資源的操作。但是如果每次只對資源賦予一個線程的訪問權限顯然是低效的,讀寫鎖的優勢是同時可以有多個線程對同一資源進行讀操作。因此在讀操作比寫操作多很多,並且寫操作的時間很短的情況下使用讀寫鎖是比較有效率的。讀寫鎖是一個非靜態類所以你在使用前需要先聲明一個讀寫鎖對象: 
static private ReaderWriterLock _rwlock = new ReaderWriterLock(); 

    讀寫鎖是通過調用AcquireReaderLock,ReleaseReaderLock,AcquireWriterLock,ReleaseWriterLock來完成讀鎖和寫鎖控制的 

        static public void ReaderThread(int thrdId) 
        { 
            
try 
            { 
// 請求讀鎖,如果100ms超時退出 
                _rwlock.AcquireReaderLock(10); 
                
try 
                { 
                    
int inx = _rand.Next(_list.Count); 
                    
if (inx < _list.Count) 
                        Console.WriteLine(
"{0}thread {1}", thrdId, _list[inx]); 
                } 
                
finally 
                {
                    _rwlock.ReleaseReaderLock(); 
                } 
            } 
            
catch (ApplicationException) // 如果請求讀鎖失敗 
            { 
                Console.WriteLine(
"{0}thread get reader lock out time!", thrdId); 
            } 
        } 
        
static public void WriterThread() 
        { 
            
try 
            {
                
// 請求寫鎖 
                _rwlock.AcquireWriterLock(100); 
                
try 
                { 
                    
string val = _rand.Next(200).ToString(); 
                    _list.Add(val); 
// 寫入資源 
                    Console.WriteLine("writer thread has written {0}", val); 
                } 
                
finally 
                { 
// 釋放寫鎖 
                    _rwlock.ReleaseWriterLock(); 
                } 
            } 
            
catch (ApplicationException) 
            { 
                Console.WriteLine(
"Get writer thread lock out time!"); 
            } 
        } 

    如果你想在讀的時候插入寫操作請使用UpgradeToWriterLock和DowngradeFromWriterLock來進行操作,而不是釋放讀鎖。

        static private void UpgradeAndDowngrade(int thrdId) 
        { 
            
try 
            { 
                _rwlock.AcquireReaderLock(
10); 
                
try 
                { 
                    
try 
                    {
                        
// 提升讀鎖到寫鎖 
                        LockCookie lc = _rwlock.UpgradeToWriterLock(100);
                        
try
                        {
                            
string val = _rand.Next(500).ToString();
                            _list.Add(val); Console.WriteLine(
"Upgrade Thread{0} add {1}", thrdId, val); 
                        } 
                        
finally
                        { 
// 下降寫鎖 
                            _rwlock.DowngradeFromWriterLock(ref lc); 
                        } 
                    } 
                    
catch (ApplicationException)
                    { 
                        Console.WriteLine(
"{0}thread upgrade reader lock failed!", thrdId); 
                    } 
                } 
                
finally 
                {
                    
// 釋放原來的讀鎖 
                    _rwlock.ReleaseReaderLock();
                }
            } 
            
catch (ApplicationException) 
            { 
                Console.WriteLine(
"{0}thread get reader lock out time!", thrdId);
            }
        }

     這裏有一點要注意的就是讀鎖和寫鎖的超時等待時間間隔的設置。通常情況下設置寫鎖的等待超時要比讀鎖的長,否則會經常發生寫鎖等待失敗的情況。

發佈了2 篇原創文章 · 獲贊 4 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章