C# ReaderWriterLock

多线程中的锁的概念是为了保证原子操作. 所谓的原子操作, 就是说对一个对象的修改需要多个步骤完成,那么我们希望这个修改动作在没有任何外部打断的情况下,从第一步到最后一步能够完整的执行完. 在多线程编程中, 可能有多个线程都会去执行这个修改动作, 那么不同的线程在对同一个对象执行同一个修改动作时, 就有可能发生抢占的行为. 就是说线程 A 的修改动作还没完成, 线程 B 就开始修改动作, 这时候被修改对象的内容就被污染了, 它既不是线程 A 期望的内容, 也不是线程 B 期望的内容. 这时候我们就可以给修改对象加上一个锁, 只有拥有该锁的线程才有资格去执行修改动作, 修改完成后, 别的进程才有机会去执行修改动作. 

最简单的锁当然就是互斥锁了, 但是对于读写来说, 可能会有多个线程读一个对象, 而只有一个线程要写这个对象. 那么对于读线程来说, 它不改变对象的内容, 我们就应该允许多个线程同时读, 只有在写的时候才要给锁住对象. 这样可以提高读线程的吞吐量.  以下介绍一个读写锁, 可以用来对 Dictionary 对象来加读写锁, 从而来实现一个同步的 Dictionary. 

使用一个ReaderWriterLock来实现一个同步的Cache, 以便控制对该Cache的读写.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

namespace ReadWriteLockSlimTest
{
    class SynchronizedCache
    {
        private ReaderWriterLockSlim cacheLock = new ReaderWriterLockSlim();
        private Dictionary innerCache = new Dictionary();

        public string Read(int key)
        {
            cacheLock.EnterReadLock();
            try
            {
                return innerCache[key];
            }
            finally
            {
                cacheLock.ExitReaderLock();
            }
        }

        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.ExitReaderLock();
                }
                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
        };
    }
}


你可能感兴趣的:(C#系列,多线程,c#,读写锁,代码)