一文带你了解.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 @   初夏的阳光丶  阅读(680)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 通过 API 将Deepseek响应流式内容输出到前端
· 因为Apifox不支持离线,我果断选择了Apipost!
点击右上角即可分享
微信分享提示