Ale*_* Dn 3 .net c# multithreading locking readerwriterlockslim
编辑:从我已经得到的答案中,我了解我提出的第一个解决方案,并不是真正的“不阻止读取”,因为只有一个线程可以输入可升级的锁,而在读取被释放之前不能采用写入锁...
所以我的问题是,如果不存在,如何以正确的方式使第一个解决方案成为“非阻塞读取”?
我试图了解两种非阻塞多线程读取的解决方案。以下两个解决方案之间有什么区别(也许我仍然不了解某些事情,但是我正在尝试):
/// <summary>
/// ReaderWriterLockSlim pattern
/// </summary>
public class ReadWriteLockCheck
{
Dictionary<string, object> _dict = new Dictionary<string, object>();
private ReaderWriterLockSlim _rwLock = new ReaderWriterLockSlim(LockRecursionPolicy.NoRecursion);
public void CreateByKey(string key)
{
_rwLock.EnterReadLock();
try
{
if (!_dict.ContainsKey(key)) //Non blocking read - Check if exists
{
_rwLock.EnterWriteLock(); //Lock
try
{
_dict.Add(key, new object());
}
finally
{
_rwLock.ExitWriteLock();
}
}
}
finally
{
_rwLock.ExitReadLock();
}
}
public bool GetByKey(string key)
{
_rwLock.EnterWriteLock();
try
{
if (_dict.ContainsKey(key)) //Non blocking read
{
return true;
}
return false;
}
finally
{
_rwLock.ExitReadLock();
}
}
}
/// <summary>
/// Double check lock pattern
/// </summary>
public class MonitorLock
{
Dictionary<string, object> _dict = new Dictionary<string, object>();
private object _syncObj = new Object();
public void CreateByKey(string key)
{
if (!_dict.ContainsKey(key)) //Non blocking read - Check if exists
{
Monitor.Enter(_syncObj); //Lock
try
{
if (!_dict.ContainsKey(key)) //Check if between first check and lock someone already added
{
_dict.Add(key, new object());
}
}
finally
{
Monitor.Exit(_syncObj);
}
}
}
public bool GetByKey(string key)
{
if (_dict.ContainsKey(key)) //Non blocking read
{
return true;
}
return false;
}
}
Run Code Online (Sandbox Code Playgroud)
在我看来,这两种解决方案都可以进行非阻塞读取,并且只能在写入时进行阻塞……如果是这样,这有什么好处ReaderWriterLockSlim?正如我在google中发现的那样,Monitor它比快得多ReaderWriterLockSlim。当然,我知道阅读时可能会得到不正确的字典状态,但对我来说还可以。
谢谢
在任何给定时间,只有一个线程可以进入可升级模式
基本上,您没有比使用完全锁定做得更好-除非lock实际上会更快。
奇怪的是,这里的一种好方法是Hashtable:特别是因为值是object,并且键是引用类型(没有多余的装箱)。Hashtable不寻常的是,读取是完全线程安全的;您只需要警惕多个作家。
例如:
readonly Hashtable lookup = new Hashtable();
...
object val = lookup[key]; // no need to synchronize when reading
...
lock(lookup)
{
lookup[key] = newVal; // synchronize when writing
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1404 次 |
| 最近记录: |