日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢(xún)
選擇下列產(chǎn)品馬上在線(xiàn)溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷(xiāo)解決方案
面試官:平時(shí)開(kāi)發(fā)中你用過(guò)讀寫(xiě)鎖嗎?

本文轉(zhuǎn)載自微信公眾號(hào)「精益碼農(nóng)」,作者小碼甲。轉(zhuǎn)載本文請(qǐng)聯(lián)系精益碼農(nóng)公眾號(hào)。

創(chuàng)新互聯(lián)建站專(zhuān)業(yè)為企業(yè)提供崆峒網(wǎng)站建設(shè)、崆峒做網(wǎng)站、崆峒網(wǎng)站設(shè)計(jì)、崆峒網(wǎng)站制作等企業(yè)網(wǎng)站建設(shè)、網(wǎng)頁(yè)設(shè)計(jì)與制作、崆峒企業(yè)網(wǎng)站模板建站服務(wù),十多年崆峒做網(wǎng)站經(jīng)驗(yàn),不只是建網(wǎng)站,更提供有價(jià)值的思路和整體網(wǎng)絡(luò)服務(wù)。

前面實(shí)現(xiàn)了一個(gè) 帶值變更通知能力的字典類(lèi)(線(xiàn)程不安全),童鞋們有沒(méi)有發(fā)現(xiàn)演示代碼使用了 lock語(yǔ)法糖, 這個(gè)有沒(méi)有問(wèn)題呢?

沒(méi)背景說(shuō)個(gè)鏟鏟

同程藝龍基礎(chǔ)架構(gòu)部推出的數(shù)據(jù)獲取組件DAL.Connection,我們要做到在切換連接配置時(shí)清空數(shù)據(jù)庫(kù)連接池, 這就涉及到切換連接的時(shí)候,觸發(fā)變更通知。

這在高并發(fā)下會(huì)有問(wèn)題:大多數(shù)時(shí)候下DBA并不會(huì)變更業(yè)務(wù)方的數(shù)據(jù)庫(kù)連接,這是一個(gè)多讀少寫(xiě)的場(chǎng)景, 我們無(wú)腦使用lock在多數(shù)時(shí)間會(huì)人為阻塞請(qǐng)求。

到這個(gè)時(shí)候,我們就要想到讀寫(xiě)鎖ReaderWriterLockSlim。

寶藏好物:ReaderWriterLockSlim

Use ReaderWriterLockSlim to protect a resource that is read by multiple threads and written to by one thread at a time. ReaderWriterLockSlim allows multiple threads to be in read mode, allows one thread to be in write mode with exclusive ownership of the lock, and allows one thread that has read access to be in upgradeable read mode, from which the thread can upgrade to write mode without having to relinquish its read access to the resource.

簡(jiǎn)而言之:

ReaderWriterLockSlim提供對(duì)某資源在某時(shí)刻下的多線(xiàn)程同讀 或 單線(xiàn)程獨(dú)占寫(xiě)。

此外,ReaderWriterLockSlim還提供從讀模式無(wú)縫升級(jí)到獨(dú)占寫(xiě)模式。

總結(jié)下來(lái):

讀寫(xiě)鎖處于以下四種狀態(tài):

1.未進(jìn)入: 沒(méi)有線(xiàn)程進(jìn)入鎖(或者所有線(xiàn)程退出鎖)

2.讀模式:每次調(diào)用EnterReadlock時(shí),鎖計(jì)數(shù)都會(huì)增加,但允許您讀取其中的代碼塊。

3.寫(xiě)模式:獨(dú)占、排他

4.可升級(jí)的讀模式(upgradeable read mode):多線(xiàn)程讀,其中一個(gè)線(xiàn)程具備在某時(shí)刻升級(jí)到排他寫(xiě)模式的可能。

btw,讀寫(xiě)鎖相比常規(guī)lock之外,還具備鎖超時(shí)的機(jī)制,能避免未知原因持續(xù)占有鎖導(dǎo)致的死鎖。

這就很適合我們開(kāi)發(fā)DAL.Connection組件的多讀少寫(xiě)的場(chǎng)景。

微軟ReaderWriterLockSlim頁(yè)面還很貼心的給了一個(gè)基于讀寫(xiě)鎖的緩存操作封裝類(lèi)SynchronizedCache。

開(kāi)箱即用的緩存操作類(lèi)

基于ReaderWriterLockSlim對(duì)線(xiàn)程不安全的Dictionary進(jìn)行了包裝, 可以作為一個(gè)多讀少寫(xiě)的緩存操作類(lèi)。

 
 
 
  1. public class SynchronizedCache  
  2.     private ReaderWriterLockSlim cacheLock = new ReaderWriterLockSlim(); 
  3.     private Dictionary innerCache = new Dictionary(); 
  4.  
  5.     public int Count 
  6.     { get { return innerCache.Count; } } 
  7.  
  8.     public string Read(int key) 
  9.     { 
  10.         cacheLock.EnterReadLock(); 
  11.         try 
  12.         { 
  13.             return innerCache[key]; 
  14.         } 
  15.         finally 
  16.         { 
  17.             cacheLock.ExitReadLock(); 
  18.         } 
  19.     } 
  20.  
  21.     public void Add(int key, string value) 
  22.     { 
  23.         cacheLock.EnterWriteLock(); 
  24.         try 
  25.         { 
  26.             innerCache.Add(key, value); 
  27.         } 
  28.         finally 
  29.         { 
  30.             cacheLock.ExitWriteLock(); 
  31.         } 
  32.     } 
  33.  
  34.     public bool AddWithTimeout(int key, string value, int timeout) 
  35.     { 
  36.         if (cacheLock.TryEnterWriteLock(timeout)) 
  37.         { 
  38.             try 
  39.             { 
  40.                 innerCache.Add(key, value); 
  41.             } 
  42.             finally 
  43.             { 
  44.                 cacheLock.ExitWriteLock(); 
  45.             } 
  46.             return true; 
  47.         } 
  48.         else 
  49.         { 
  50.             return false; 
  51.         } 
  52.     } 
  53.  
  54.     public AddOrUpdateStatus AddOrUpdate(int key, string value) 
  55.     { 
  56.         cacheLock.EnterUpgradeableReadLock(); 
  57.         try 
  58.         { 
  59.             string result = null; 
  60.             if (innerCache.TryGetValue(key, out result)) 
  61.             { 
  62.                 if (result == value) 
  63.                 { 
  64.                     return AddOrUpdateStatus.Unchanged; 
  65.                 } 
  66.                 else 
  67.                 { 
  68.                     cacheLock.EnterWriteLock(); 
  69.                     try 
  70.                     { 
  71.                         innerCache[key] = value; 
  72.                     } 
  73.                     finally 
  74.                     { 
  75.                         cacheLock.ExitWriteLock(); 
  76.                     } 
  77.                     return AddOrUpdateStatus.Updated; 
  78.                 } 
  79.             } 
  80.             else 
  81.             { 
  82.                 cacheLock.EnterWriteLock(); 
  83.                 try 
  84.                 { 
  85.                     innerCache.Add(key, value); 
  86.                 } 
  87.                 finally 
  88.                 { 
  89.                     cacheLock.ExitWriteLock(); 
  90.                 } 
  91.                 return AddOrUpdateStatus.Added; 
  92.             } 
  93.         } 
  94.         finally 
  95.         { 
  96.             cacheLock.ExitUpgradeableReadLock(); 
  97.         } 
  98.     } 
  99.  
  100.     public void Delete(int key) 
  101.     { 
  102.         cacheLock.EnterWriteLock(); 
  103.         try 
  104.         { 
  105.             innerCache.Remove(key); 
  106.         } 
  107.         finally 
  108.         { 
  109.             cacheLock.ExitWriteLock(); 
  110.         } 
  111.     } 
  112.  
  113.     public enum AddOrUpdateStatus 
  114.     { 
  115.         Added, 
  116.         Updated, 
  117.         Unchanged 
  118.     }; 
  119.  
  120.     ~SynchronizedCache() 
  121.     { 
  122.        if (cacheLock != null) cacheLock.Dispose(); 
  123.     } 

緩存操作類(lèi)SynchronizedCache每次操作會(huì)返回操作結(jié)果,和常見(jiàn)的字典一樣,不帶值變更通知的能力,我們還是像《面試官:實(shí)現(xiàn)一個(gè)帶值變更通知能力的Dictionary》 一文那樣,添加值變更事件,注冊(cè)變更邏輯。

 
 
 
  1. public event EventHandler> OnValueChanged; 
  2.  
  3. //--- 節(jié)選自AddOrUpdate方法 
  4. cacheLock.EnterWriteLock(); 
  5. try 
  6.    OnValueChanged?.Invoke(this, new ValueChangedEventArgs(key)); 
  7.    innerCache[key] = value; 
  8. finally 
  9.     cacheLock.ExitWriteLock(); 
  10. return AddOrUpdateStatus.Updated; 
  11.                          
  12. //--- 
  13.  
  14. if (sc.AddOrUpdate(key, value) == SynchronizedCache.AddOrUpdateStatus.Updated) 
  15.     Console.WriteLine($"已經(jīng)發(fā)生了值變更,原key對(duì)應(yīng)的鍵值已經(jīng)被重寫(xiě)。");} 
  16. }   

輸出旁白

本文記錄了讀寫(xiě)鎖在日常開(kāi)發(fā)中的實(shí)踐,大多數(shù)場(chǎng)景都是多讀少寫(xiě),讀者可以思考一下是不是也可以將項(xiàng)目中的無(wú)腦lock替換為SynchronizedCache。

本文是同程藝龍DAL.Connection組件研發(fā)過(guò)程的一個(gè)小插曲,有心的讀者可以往上翻一翻,了解上下文背景、了解小碼甲的思考過(guò)程。


新聞名稱(chēng):面試官:平時(shí)開(kāi)發(fā)中你用過(guò)讀寫(xiě)鎖嗎?
網(wǎng)址分享:http://www.5511xx.com/article/dhsceoj.html