成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

面試官: 平時(shí)開發(fā)中你用過讀寫鎖嗎?

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

[[420812]]

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

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

沒背景說個(gè)鏟鏟

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

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

到這個(gè)時(shí)候,我們就要想到讀寫鎖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.

簡而言之:

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

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

總結(jié)下來:

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

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

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

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

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

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

這就很適合我們開發(fā)DAL.Connection組件的多讀少寫的場景。

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

開箱即用的緩存操作類

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

  1. public class SynchronizedCache  
  2.     private ReaderWriterLockSlim cacheLock = new ReaderWriterLockSlim(); 
  3.     private Dictionary<int, string> innerCache = new Dictionary<int, string>(); 
  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(keyout 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.     } 

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

  1. public event EventHandler<ValueChangedEventArgs<string>> OnValueChanged; 
  2.  
  3. //--- 節(jié)選自AddOrUpdate方法 
  4. cacheLock.EnterWriteLock(); 
  5. try 
  6.    OnValueChanged?.Invoke(this, new ValueChangedEventArgs<string>(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)被重寫。");} 
  16. }   

輸出旁白

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

 

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

 

責(zé)任編輯:武曉燕 來源: 精益碼農(nóng)
相關(guān)推薦

2024-08-12 17:36:54

2020-09-16 07:56:28

多線程讀寫鎖悲觀鎖

2022-07-04 08:06:14

Go語言互斥鎖

2022-10-08 00:08:00

apiESFacebook

2025-02-26 12:19:52

2015-08-13 10:29:12

面試面試官

2023-08-11 17:13:39

JavaScrip

2022-07-12 12:05:22

JavaSemaphore

2021-07-09 10:11:34

Redis云數(shù)據(jù)技術(shù)

2021-03-11 08:51:00

存儲(chǔ)面試位置

2023-01-12 08:24:45

ZookeeperZK服務(wù)器

2020-09-26 22:04:32

數(shù)據(jù)安全傳輸HTTPSHTTP 協(xié)議

2023-11-10 08:44:13

分布式鎖分布式系統(tǒng)

2021-09-01 09:44:16

Redis持久化配置

2024-04-02 09:45:27

線程池Executors開發(fā)

2021-12-16 18:38:13

面試Synchronize

2019-06-21 15:20:05

Redis數(shù)據(jù)結(jié)構(gòu)數(shù)據(jù)庫

2025-03-05 00:00:00

RTKRedux開發(fā)

2021-07-05 07:55:11

String[]byte轉(zhuǎn)換

2024-03-12 10:44:42

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 久久久国产一区 | 国产一区二区三区四区 | 黄色一级大片在线免费看产 | 一级黄色播放 | 91亚洲精品国偷拍自产在线观看 | 影音先锋男 | 国内自拍偷拍视频 | 免费一区二区 | 欧美1页 | 欧美精品网站 | 91av在线免费 | 一区二区三区影院 | jlzzjlzz欧美大全 | 国产日韩精品一区二区三区 | 四虎影视一区二区 | 免费在线观看av | 国产精品日日摸夜夜添夜夜av | 超碰人人人 | 久久久精品一区 | 国产农村妇女毛片精品久久麻豆 | 日韩免费看视频 | 亚洲国产成人久久综合一区,久久久国产99 | 欧美日韩在线一区二区 | 91久久国产综合久久 | 色视频欧美 | 精品国产女人 | 日本一区二区三区四区 | 日本精品视频一区二区三区四区 | 激情五月婷婷在线 | 成人在线不卡 | 久久精品中文字幕 | 五月天婷婷久久 | 欧美日本高清 | 国产激情在线 | 欧美亚州| 日本欧美国产 | 欧美九九 | 欧美成人一区二区三区 | 国产视频精品在线观看 | 一区二区免费视频 | 99视频网站 |