C# ReaderWriterLockSlim类

Posted dotNET跨平台

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C# ReaderWriterLockSlim类相关的知识,希望对你有一定的参考价值。

为了使锁定机制允许锁定多个读取器(而不是一个写入器)访问某个资源,可以使用 ReaderWriterLockSlim 类。这个类提供了一个锁定功能,如果没有写入器锁定资源,就允许多个读取器访问资源,但只能有一个写入器锁定该资源。

ReaderWriterLockSlim 类有阻塞或不阻塞的方法来获取读取锁,如阻塞的EnterReadLock() 和不阻塞的 TryEnterReadLock() 方法,还可以使用阻塞的EnterWriteLock() 和不阻塞的 TryEnterWriteLock() 方法获得写入锁定。如果任务先读取资源,之后写入资源,它就可以使用 EnterUpgradableReadLock() 或 TryEnterUpgradableReadLock() 方法获得可升级的读取锁定。有了这个锁定,就可以获得写入锁定,而不需要释放读取锁定。

这个类的几个属性提供了当前锁定的相关信息。如CurrentReadCount、WaitingReadCount、WaitingUpgradableReadCount 和 WaitingWriteCount。

下面的示例程序创建了一个包含 6 项的集合和一个 ReaderWriterLockSlim() 对象。ReaderMethod() 方法获得一个读取锁定,读取列表中的所有项,并把它们写到控制台中。WriterMethod(0 方法试图获得一个写入锁定,以改变集合的所有值。在Main()方法中,启动6个任务,以调用 ReaderMethod()或WriterMethod()方法。

class Program

  private static List<int> _items = new List<int>()  0,1,2,3,4,5; 
  private static ReaderWriterLockSlim _rwl =
    new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);


  public static void ReaderMethod(object reader)

    try
    
      _rwl.EnterReadLock();
      For (int i = 0; i < _items.Count; i++)
      
        Console.WriteLine($"reader reader, loop: i, item: _items[i]"); 
        Task.Delay(40).Wait();
      
    
    finally
    
          _rwl.ExitReadLock();
        
      
      
      public static void WriterMethod(object writer)

        try
        
          while (!_rwl.TryEnterWriteLock(50))
          
            Console.WriteLine($"Writer writer waiting for the write lock"); 
            Console.WriteLine($"current reader count:(_rwl.CurrentReadCount");
          
          Console.WriteLine($"Writer writer) acquired the lock");
          for (int i = 0; i < _items.Count; i++)
          
            _items[i]++;
            Task.Delay(50).Wait();
          
          Console.WriteLine($"Writer writer finished");
        
        finally
        
          _rwl.ExitWriteLock();
        
      


      static void Main()

        var taskFactory = new TaskFactory(TaskCreationOptions.LongRunning,
          TaskContinuationOptions.None); 
        var tasks = new Task[6];
        tasks[0] = taskFactory.StartNew(WriterMethod, 1); 
        tasks[1] = taskFactory.StartNew(ReaderMethod, 1);
        tasks[2] = taskFactory.StartNew(ReaderMethod, 2);
        tasks[3] = taskFactory.StartNew(WriterMethod, 2);
        tasks[4] = taskFactory.StartNew(ReaderMethod, 3); 
        tasks[5] = taskFactory.StartNew(ReaderMethod, 4); 
        Task.WaitAll(tasks);
      
    

运行这个应用程序,可以看到第一个写入器先获得锁定。第二个写入器和所有的读取器需要等待。接着,读取器可以同时工作,而第二个写入器仍在等待资源。 

Writer 1 acquired the lock
Writer 2 waiting for the write lock 
current reader count: 0
Writer 2 waiting for the write lock 
current reader count: 0
Writer 2 waiting for the write lock 
current reader count: 0
Writer 2 waiting for the write lock 
current reader count: 0 
Writer 1 finished
reader 4, loop: 0,item: 1 
reader 1, loop: 0, item: 1
Writer 2 waiting for the write lock 
current reader count: 4
reader 2, loop: 0,item: 1 
reader 3, loop: 0, item: 1 
reader 4,loop: 1, item: 2 
reader 1, loop: 1, item: 2
reader 3, loop: 1,item: 2
reader 2, loop: 1, item: 2 
Writer 2 waiting for the write lock 
current reader count: 4
reader 4, loop: 2, item: 3 
reader l, loop: 2,item: 3
reader 2, loop: 2,item: 3 
reader 3, loop: 2, item: 3
Writer 2 waiting for the write lock 
current reader count: 4
reader 4, loop: 3, item: 4 
reader 1, loop: 3,item: 4
reader 2, loop: 3, item: 4 
reader 3, loop: 3, item: 4
reader 4, loop: 4, item: 5 
reader 1, loop: 4, item: 5
Writer 2 waiting for the write lock 
current reader count: 4
reader 2, loop: 4, item: 5
reader 3, loop: 4, item: 5 
reader 4, loop: 5, item: 6 
reader 1,loop: 5,item: 6
reader 2, loop: 5, item: 6
reader 3, loop: 5, item: 6
Writer 2 waiting for the write lock 
current reader count: 4
Writer 2 acquired the lock 
Writer 2 finished

 微信公众号 

Dotnet讲堂

以上是关于C# ReaderWriterLockSlim类的主要内容,如果未能解决你的问题,请参考以下文章

C# - 为啥在使用 ReaderWriterLockSlim 时出现 LockRecursionException?

C# 多线程并发锁模式-总结

线程同步-使用ReaderWriterLockSlim类

读写锁-ReaderWriterLockSlim

读写锁-ReaderWriterLockSlim

《C#高级编程》读书笔记(十五):任务线程和同步之四 同步