读写锁:
ReaderWriterLockSlim
可以多线程读,但只有一个线程写入;并且写入的时候不能读取,读取的时候不能写入。具体代码如下
测试代码:
public class TestReadAndWriteLock { SynchronizedCache cache = new SynchronizedCache(); //Dictionary<int, string> cache = new Dictionary<int, string>(); public void Run() { for (int i = 0; i < 100; i++) { TaskAdd(i); } for (int i = 0; i < 100; i++) { TaskRead(i); } Console.ReadLine(); } public void TaskAdd(int i) { Task.Factory.StartNew(() => { cache.Add(i, i.ToString()); }); } public void TaskRead(int i) { Task.Factory.StartNew(() => { string value = cache.Read(i); //string value = cache[i]; Console.WriteLine(value); }); } }
缓存代码:
public class SynchronizedCache { private ReaderWriterLockSlim cacheLock = new ReaderWriterLockSlim(); private Dictionary<int, string> innerCache = new Dictionary<int, string>(); public int Count { get { return innerCache.Count; } } public string Read(int key) { cacheLock.EnterReadLock(); try { return innerCache[key]; } finally { cacheLock.ExitReadLock(); } } public void Add(int key, string value) { cacheLock.EnterWriteLock(); try { innerCache.Add(key, value); } finally { cacheLock.ExitWriteLock(); } } public bool AddWithTimeout(int key, string value, int timeout) { if (cacheLock.TryEnterWriteLock(timeout)) { try { innerCache.Add(key, value); } finally { cacheLock.ExitWriteLock(); } return true; } else { return false; } } public AddOrUpdateStatus AddOrUpdate(int key, string value) { cacheLock.EnterUpgradeableReadLock(); try { string result = null; if (innerCache.TryGetValue(key, out result)) { if (result == value) { return AddOrUpdateStatus.Unchanged; } else { cacheLock.EnterWriteLock(); try { innerCache[key] = value; } finally { cacheLock.ExitWriteLock(); } return AddOrUpdateStatus.Updated; } } else { cacheLock.EnterWriteLock(); try { innerCache.Add(key, value); } finally { cacheLock.ExitWriteLock(); } return AddOrUpdateStatus.Added; } } finally { cacheLock.ExitUpgradeableReadLock(); } } public void Delete(int key) { cacheLock.EnterWriteLock(); try { innerCache.Remove(key); } finally { cacheLock.ExitWriteLock(); } } public enum AddOrUpdateStatus { Added, Updated, Unchanged }; ~SynchronizedCache() { if (cacheLock != null) cacheLock.Dispose(); } }