C#實(shí)現(xiàn)讀寫(xiě)分離的五種方法小結(jié)
1. 使用 ReaderWriterLockSlim
.NET 提供的高性能讀寫(xiě)鎖,支持以下模式:
讀模式(Read Lock):允許多個(gè)線程同時(shí)讀取。
寫(xiě)模式(Write Lock):獨(dú)占鎖,其他所有讀寫(xiě)操作都會(huì)被阻塞。
using System.Threading; public class ReadWriteExample { private readonly ReaderWriterLockSlim _lock = new ReaderWriterLockSlim(); private int _sharedData = 0; // 讀操作 public int ReadData() { _lock.EnterReadLock(); try { return _sharedData; } finally { _lock.ExitReadLock(); } } // 寫(xiě)操作 public void WriteData(int value) { _lock.EnterWriteLock(); try { _sharedData = value; } finally { _lock.ExitWriteLock(); } } }
優(yōu)點(diǎn):
細(xì)粒度控制讀寫(xiě)操作。
支持遞歸鎖和超時(shí)機(jī)制。
缺點(diǎn):
需要手動(dòng)管理鎖的獲取和釋放。
2. 使用 Concurrent 并發(fā)集合
.NET 的 System.Collections.Concurrent
命名空間提供了線程安全的集合類(lèi),內(nèi)部已實(shí)現(xiàn)讀寫(xiě)分離邏輯:
ConcurrentDictionary<TKey, TValue>
ConcurrentQueue<T>
ConcurrentBag<T>
using System.Collections.Concurrent; public class ConcurrentExample { private readonly ConcurrentDictionary<string, int> _data = new(); // 讀操作(無(wú)鎖) public int GetValue(string key) { return _data.TryGetValue(key, out int value) ? value : -1; } // 寫(xiě)操作(內(nèi)部使用細(xì)粒度鎖) public void UpdateValue(string key, int value) { _data.AddOrUpdate(key, value, (k, oldValue) => value); } }
優(yōu)點(diǎn):
開(kāi)箱即用,無(wú)需手動(dòng)管理鎖。
高性能,適合高頻讀寫(xiě)場(chǎng)景。
缺點(diǎn):
靈活性較低,僅適用于預(yù)定義的集合類(lèi)型。
3. 基于 volatile 和內(nèi)存屏障(Memory Barrier)
適用于簡(jiǎn)單變量的讀寫(xiě)分離,通過(guò) volatile
關(guān)鍵字確保內(nèi)存可見(jiàn)性:
public class VolatileExample { private volatile bool _flag = false; private int _data = 0; // 讀操作(無(wú)鎖) public int ReadData() { if (_flag) return _data; return -1; } // 寫(xiě)操作(需要同步) public void WriteData(int value) { Interlocked.Exchange(ref _data, value); // 原子寫(xiě)入 Volatile.Write(ref _flag, true); // 確保寫(xiě)入對(duì)其他線程可見(jiàn) } }
優(yōu)點(diǎn):
輕量級(jí),適合簡(jiǎn)單場(chǎng)景。
無(wú)鎖讀操作。
缺點(diǎn):
僅適用于簡(jiǎn)單類(lèi)型(如
int
、bool
)。需要手動(dòng)處理內(nèi)存可見(jiàn)性。
4. 數(shù)據(jù)庫(kù)讀寫(xiě)分離
在數(shù)據(jù)庫(kù)層面實(shí)現(xiàn)讀寫(xiě)分離(如主從架構(gòu)),C# 代碼通過(guò)不同連接字符串路由請(qǐng)求:
public class DatabaseRouter { private static readonly string ReadConnectionString = "Server=ReadServer;..."; private static readonly string WriteConnectionString = "Server=WriteServer;..."; public IDbConnection GetReadConnection() => new SqlConnection(ReadConnectionString); public IDbConnection GetWriteConnection() => new SqlConnection(WriteConnectionString); } // 使用示例 using (var readConn = DatabaseRouter.GetReadConnection()) { // 執(zhí)行查詢(xún)操作 } using (var writeConn = DatabaseRouter.GetWriteConnection()) { // 執(zhí)行更新操作 }
優(yōu)點(diǎn):
直接利用數(shù)據(jù)庫(kù)主從復(fù)制特性。
減輕主庫(kù)壓力。
缺點(diǎn):
需要數(shù)據(jù)庫(kù)支持主從同步。
可能存在數(shù)據(jù)同步延遲。
5. 基于不可變數(shù)據(jù)(Immutable Data)
通過(guò)每次修改生成新對(duì)象實(shí)現(xiàn)無(wú)鎖讀取(如使用 ImmutableList<T>
或自定義不可變類(lèi)型):
using System.Collections.Immutable; public class ImmutableExample { private ImmutableList<int> _data = ImmutableList<int>.Empty; // 讀操作(無(wú)鎖) public int GetItem(int index) { return _data[index]; } // 寫(xiě)操作(原子替換) public void AddItem(int item) { ImmutableInterlocked.Update(ref _data, list => list.Add(item)); } }
優(yōu)點(diǎn):
完全無(wú)鎖讀取。
天然線程安全。
缺點(diǎn):
頻繁修改可能產(chǎn)生內(nèi)存壓力。
選擇策略
場(chǎng)景 | 推薦方案 |
---|---|
細(xì)粒度代碼級(jí)讀寫(xiě)控制 | ReaderWriterLockSlim |
高頻并發(fā)集合操作 | ConcurrentDictionary 等并發(fā)集合 |
簡(jiǎn)單變量的讀寫(xiě) | volatile + Interlocked |
數(shù)據(jù)庫(kù)訪問(wèn)分離 | 主從架構(gòu) + 連接路由 |
高頻讀、低頻寫(xiě) | 不可變數(shù)據(jù)(如 ImmutableList ) |
注意事項(xiàng)
避免死鎖:確保鎖的獲取和釋放成對(duì)出現(xiàn)(用
try-finally
塊)。性能權(quán)衡:讀寫(xiě)鎖適合讀多寫(xiě)少場(chǎng)景,寫(xiě)頻繁時(shí)可能不如普通鎖高效。
數(shù)據(jù)一致性:數(shù)據(jù)庫(kù)讀寫(xiě)分離時(shí)需處理主從同步延遲問(wèn)題。
到此這篇關(guān)于C#實(shí)現(xiàn)讀寫(xiě)分離的五種方法小結(jié)的文章就介紹到這了,更多相關(guān)C#讀寫(xiě)分離內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C#中IDispose接口的實(shí)現(xiàn)及為何這么實(shí)現(xiàn)詳解
這篇文章主要給大家介紹了關(guān)于C#中IDispose接口的實(shí)現(xiàn)及為何這么實(shí)現(xiàn)的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2018-05-05C# 建造者模式(Builder Pattern)詳細(xì)講解
建造者模式是一種創(chuàng)建型設(shè)計(jì)模式,通過(guò)將復(fù)雜對(duì)象的構(gòu)建過(guò)程與其表示分離,使得同樣的構(gòu)建過(guò)程可以創(chuàng)建不同的表示,它適用于構(gòu)建過(guò)程復(fù)雜且涉及多個(gè)步驟的場(chǎng)景,本文介紹C# 建造者模式(Builder Pattern)詳細(xì)講解,感興趣的朋友一起看看吧2025-03-03