主线程和子线程会操作同一个List,主线程读,子线程写入。两个线程不能同时处理这个List,所以用了个读写锁,但是发现Timer启动的任务里面,对slim的操作不会反馈到主线程。也可能是我对IsWriteLockHeld这个属性理解错误,下面是测试代码,来个大佬帮看看吧
using System.Threading;
ReaderWriterLockSlim slim;
void Main()
{ slim = new ReaderWriterLockSlim();
slim.TryEnterWriteLock(10);
//Console.WriteLine("主线程拿写锁:" + slim.IsWriteLockHeld);
Console.WriteLine("主线程查看读写锁是不是写锁定:" + slim.IsWriteLockHeld);
Timer timer = new Timer((obj) => LoadMessage(obj),
slim, 0, 10 * 1000);
while(true)
{
Thread.Sleep(13*1000); //13是为了卡timer进程的写锁定
if(slim.IsWriteLockHeld)
{
slim.ExitWriteLock();
Console.WriteLine("主线程放掉了锁");
}
Console.WriteLine("主线程查看读写锁是不是写锁定:" + slim.IsWriteLockHeld);
}
}
// You can define other methods, fields, classes and namespaces here
private void LoadMessage(object slimObject)
{
//Console.WriteLine(Object.ReferenceEquals(slim,slimObject));
var localslim = slimObject as ReaderWriterLockSlim;
//Console.WriteLine(Object.ReferenceEquals(slim,localslim));
if (localslim.IsReadLockHeld || localslim.IsWriteLockHeld)
{
Console.WriteLine("读或写状态中");
return;
}
if (!localslim.TryEnterWriteLock(1 * 1000))
{
Console.WriteLine("子线程写状态:" + localslim.IsWriteLockHeld);
Console.WriteLine("子线程获取写锁失败");
return;
}
Console.WriteLine("子线程拿到了写锁");
try
{
//Console.WriteLine("引用地址是否相同:" + Object.ReferenceEquals(slim,localslim));
Thread.Sleep(18*1000); //模拟延时操作,18秒为了让第二次拿不到写锁
//Console.WriteLine("子线程是否拿到了写锁:"+ localslim.IsWriteLockHeld);
}
finally
{
localslim.ExitWriteLock();
Console.WriteLine("子线程释放了写锁");
}
}
主线程拿写锁:True
主线程查看读写锁是不是写锁定:True
子线程写状态:False
子线程获取写锁失败
子线程写状态:False
子线程获取写锁失败
主线程放掉了锁
主线程查看读写锁是不是写锁定:False
子线程拿到了写锁
引用地址是否相同:True
主线程查看读写锁是不是写锁定:False
子线程写状态:False
子线程获取写锁失败
子线程是否拿到了写锁:True
子线程释放了写锁
主线程查看读写锁是不是写锁定:False
子线程拿到了写锁
引用地址是否相同:True
子线程写状态:False
...
读写锁具有线程关联性,即两个线程间拥有的锁的状态相互独立不受影响、并且不能相互修改其锁的状态。
更多请阅读:
https://www.cnblogs.com/majiang/p/8133979.html