一文带你了解.Net读写锁

在这里插入图片描述
本文主要讲解.Net基于ReaderWriterLockSlim讲解读写锁


基础概念

  • 读写锁是一个具有特殊用途的线程锁,适用于频繁读取且读取需要一定时间的场景,共享资源的读取操作通常是可以同时执行的,
  • 普通的互斥锁不管是获取还是修改操作无法同时执行,如果多个线程为了读取操作而获取互斥锁,那么同一时间只有一个线程可以执行读取操作,
  • 频繁读取的场景下回对吞吐量造成影响
  • 读写锁把锁分为读取锁和写入锁,线程可以根据对共享资源的操作类型获取读取锁还是写入锁,读取锁可以被多个线程同时获取,写入锁不可以被多个线程
  • 同时获取,且读取锁和写入锁不可以被不同的线同时获取,
操作 读取锁状态 写入锁状态 获取锁是否需要等待
获取读取锁 未获取 未获取 无需等待
获取读取锁 已被其他线程获取 未获取 无需等待
获取读取锁 未获取 已被其他线程获取 需要等待其他线程释放
获取写入锁 未获取 未获取 无需等待
获取写入锁 已被其他线程获取 未获取 需要等待其他线程释放
获取写入锁 未获取 已被其他线程获取 需要等待其他线程释放

代码示例

 class Program
    {
        static void Main(string[] args)
        {
            var c = ReadWriteLockDemo.GetValue("value", x =>
              {
                  Console.WriteLine(x);
                  return x;
              });

            Console.WriteLine("结束了");
            Console.WriteLine($@"获取到的结果为:{c}");
        }
    }

public static class ReadWriteLockSimpleDemo
    {
        private static ReaderWriterLockSlim _lock = new ReaderWriterLockSlim();

        private static int _countA = 0;

        public static int _countB = 0;

        /// <summary>
        /// 增加
        /// </summary>
        public static void IncrementCounters()
        {
            _lock.EnterWriteLock();
            try
            {
                ++_countA;
                ++_countB;
            }
            finally
            {

                _lock.ExitWriteLock();
            }
        }

        /// <summary>
        /// 获取
        /// </summary>
        /// <param name="countA"></param>
        /// <param name="countB"></param>
        public static void GetCounters(ref int countA, ref int countB)
        {
            _lock.EnterReadLock();
            try
            {
                countA = _countA;
                countB = _countB;
            }
            finally
            {
                _lock.ExitReadLock();
            }
        }
    }

升级版


public static class ReadWriteLockDemo
    {
        private static ReaderWriterLockSlim _lock = new ReaderWriterLockSlim();
        private static Dictionary<string, string> _dict = new Dictionary<string, string>();

        public static string GetValue(string key, Func<string, string> factory)
        {
            _lock.EnterUpgradeableReadLock();
            try
            {
                //值已生成时可以直接返回
                if (_dict.TryGetValue(key, out var value))
                {
                    return value;
                }
                //获取(升级到)写入锁
                _lock.EnterWriteLock();
                try
                {
                    //再次判断值是否已生成
                    if (!_dict.TryGetValue(key, out value))
                    {
                        value = factory(key);
                        _dict.Add(key, value);
                    }
                    return value;
                }
                finally
                {
                    //释放写入锁
                    _lock.ExitWriteLock();
                }
            }
            finally
            {
                //释放读取锁
                _lock.ExitUpgradeableReadLock();
            }
        }
    }


本文基于.Net Core底层入门总结内容

如有哪里讲得不是很明白或是有错误,欢迎指正
如您喜欢的话不妨点个赞收藏一下吧🙂

posted @ 2021-09-17 20:18  初夏的阳光丶  阅读(660)  评论(0编辑  收藏  举报