代码改变世界

读写锁操作(ReaderWriterLockSlim)

  Clingingboy  阅读(1766)  评论(0编辑  收藏  举报

    
(1)

static void WriterMethod(object writer)
{
    Console.WriteLine("Writer {0} acquired the lock", writer);
    for (int i = 0; i < items.Count; i++)
    {
        items[i]++;
        Console.Write(items[i]);
    }
    Console.WriteLine("");
    Console.WriteLine("Writer {0} finished", writer);
}

private static List<int> items = new List<int>() { 0, 1, 2, 3, 4, 5 };

static void Main()
{
    WriterMethod(0);
    WriterMethod(1);

}

image
没问题
(2)换成线程
for (int i = 0; i < 2; i++)
{
    Thread a = new Thread(WriterMethod);
    a.Start(i);
}

顺序出错了
image

(3)使用读写锁操作ReaderWriterLockSlim
使用EnterWriteLock锁定写操作,恢复正常,必须手动退出锁模式,否则将会永远独占ExitWriteLock

  static void WriterMethod(object writer)
  {
      rwl.EnterWriteLock();
      Console.WriteLine("Writer {0} acquired the lock", writer);
      for (int i = 0; i < items.Count; i++)
      {
          items[i]++;
          Console.Write(items[i]);
      }
      Console.WriteLine("");
      Console.WriteLine("Writer {0} finished", writer);
      rwl.ExitWriteLock();
  }
  private static ReaderWriterLockSlim rwl = new
ReaderWriterLockSlim(LockRecursionPolicy.NoRecursion);


(4)设置锁超时时间
使用Try方法是可以设置锁时间,如果超时的话,则继续执行,但此时则未进入锁定状态,无法用ExitWriteLock退出,可以用
RecursiveWriteCount属性来判断

static void WriterMethod(object writer)
{
    rwl.TryEnterWriteLock(50);
    Console.WriteLine("Writer {0} acquired the lock", writer);
    for (int i = 0; i < items.Count; i++)
    {
        items[i]++;
        Console.Write(items[i]);
        Thread.Sleep(50);
    }
    Console.WriteLine("");
    Console.WriteLine("Writer {0} finished", writer);
    if(rwl.RecursiveWriteCount>0)
    rwl.ExitWriteLock();
}
结果照样混乱
image

(5)读写操作(单一执行)

读写操作同时进行
for (int i = 0; i < 2; i++)
{
    Thread a = new Thread(WriterMethod);
    Thread b = new Thread(ReaderMethod);
    b.Start(i);
    a.Start(i);
    
}

static void ReaderMethod(object reader)
{

    for (int i = 0; i < items.Count; i++)
    {
        Console.WriteLine("reader {0}, loop: {1}, item: {2}",
              reader, i, items[i]);
       
    }
    }

结果是混乱的,无法预测

image

进入读操作

static void ReaderMethod(object reader)
{
    rwl.EnterReadLock();
    for (int i = 0; i < items.Count; i++)
    {
        Console.WriteLine("reader {0}, loop: {1}, item: {2}",
              reader, i, items[i]);
     
    }
    rwl.ExitReadLock();
   
}

现在读写操作是单一执行的,不可能同时处于读写状态
image
同样EnterReadLock也有Try方法


另外参见
http://www.cnblogs.com/lucifer1982/archive/2008/12/07/1349437.html

编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
历史上的今天:
2009-05-13 prism behavior图示
点击右上角即可分享
微信分享提示