C# ReaderWriterLockSlim
2021-01-05 18:28
标签:示例 may public 单线程 run 获取 test string success ReaderWriterLockSlim-多线程读单线程写 注意事项 (1)线程A如果通过EnterReadLock获取到读锁(ReadLock)后,不能在持有读锁的情况下再申请获取写锁(WriteLock) 如果违反了这个规定就报如下错: (2)线程A如果通过EnterReadLock获取到读锁(ReadLock)后,不能在持有读锁的情况下再申请获取可升级读锁(UpgradeableReadLock) 如果违反了这个规定就报如下错: (3)线程A如果通过EnterUpgradeableReadLock获取到可升级读锁(UpgradeableReadLockk)后,可以再持有可升级读锁的情况通过EnterWriteLock获取写锁 递归锁 递归锁:同一个线程获取到该锁后可以再获取该锁多次,不会产生死锁。 使用默认构造函数构造的ReaderWriterLockSlim是不允许锁递归的,如果一个线程已经获取到该锁后又获取该锁就会出错,如报错“Recursive upgradeable lock acquisitions not allowed in this mode” 示例如下: 解决方法:使用允许递归锁的构造方法(即new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion))构造ReaderWriterLockSlim实例 如何判断代码逻辑里会触发递归锁呢,抓住两个要点“同一线程(即ManageThreadId一样)”和“同一个锁”,在线程池里运行的时候,由于可以重用工作线程,很容易触发递归锁的问题,比如这样:线程池线程1获取到UpgradeableReadLock锁后由于后面代码里有长时等待任务,调度器可能调度线程1运行队列里的另一个同样代码的任务,这时由于代码一样线程1再次申请获取UpgradeableReadLock锁(因为上一次他已经获取到该UpgradeableReadLock锁了),就会报错了 示例代码: 运行结果: C# ReaderWriterLockSlim 标签:示例 may public 单线程 run 获取 test string success 原文地址:https://www.cnblogs.com/tomorrow0/p/14223556.html
Write lock may not be acquired with read lock held. This pattern is prone to deadlocks. Please ensure that read locks are released before taking a write lock. If an upgrade is necessary, use an upgrade lock in place of the read lock.
Upgradeable lock may not be acquired with read lock held static void Main()
{
ReaderWriterLockSlimTest();
Console.Read();
}
public static void ReaderWriterLockSlimTest()
{
Console.WriteLine($"主线程Id : {Thread.CurrentThread.ManagedThreadId}");
// 定义共享资源
var list = new Liststring>();
// 定义ReaderWriterLockSlim共享实例
//ReaderWriterLockSlim readerWriterLockSlim = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion); // 允许递归锁
ReaderWriterLockSlim readerWriterLockSlim = new ReaderWriterLockSlim();
//TaskMethod0102("task1", 1, list, readerWriterLockSlim);
var task1 = Task.Run(() => TaskMethod0102("task1", 1, list, readerWriterLockSlim));
var task2 = Task.Run(() => TaskMethod0102("task2", 2, list, readerWriterLockSlim));
var task3 = Task.Run(() => TaskMethod0102("task3", 3, list, readerWriterLockSlim));
//var thread1 = new Thread(() => TaskMethod0102("task1", 1, list, readerWriterLockSlim));
//var thread2 = new Thread(() => TaskMethod0102("task2", 1, list, readerWriterLockSlim));
//var thread3 = new Thread(() => TaskMethod0102("task3", 1, list, readerWriterLockSlim));
}
public static string TaskMethod0102(string taskName,double seconds,Liststring> list,ReaderWriterLockSlim readerWriterLockSlim)
{
try
{
Console.WriteLine($"{taskName} want to Read ,线程Id:{Thread.CurrentThread.ManagedThreadId}");
//readerWriterLockSlim.EnterReadLock(); // 尝试获取读锁
readerWriterLockSlim.EnterUpgradeableReadLock(); // 尝试获取可升级读锁
Console.WriteLine($"{taskName} success to Read ,集合总数:{(list == null ? 0 : list.Count)} ,线程Id:{Thread.CurrentThread.ManagedThreadId}");
Console.WriteLine($"{taskName} want to Write ,线程Id:{Thread.CurrentThread.ManagedThreadId}");
readerWriterLockSlim.EnterWriteLock();
Console.WriteLine($"{taskName} success to Write ,线程Id:{Thread.CurrentThread.ManagedThreadId}");
list.Add(taskName);
return "OK";
}
catch(Exception ex)
{
return "发生异常,异常信息:" + ex.Message;
}
finally
{
Console.WriteLine($"{taskName } 释放所有的锁 ,线程Id:{Thread.CurrentThread.ManagedThreadId}");
readerWriterLockSlim.ExitUpgradeableReadLock();
readerWriterLockSlim.ExitWriteLock();
}
}
下一篇:c#中的委托(一)
文章标题:C# ReaderWriterLockSlim
文章链接:http://soscw.com/index.php/essay/40326.html