編集:私がすでに得た答えから、私が提示した最初の解決策は、実際には「読み取りをブロックしない」ではないことを理解しています。これは、読み取りが解放される前に1つのスレッドのみがアップグレード可能なロックに入ることができ、書き込みロックを取得できないためです...
だから私の質問、存在しない場合は作成で「読み取りをブロックしない」という最初の解決策を正しい方法で作成するにはどうすればよいですか?
マルチスレッド読み取りをブロックしないための2つの解決策を理解しようとしています。以下の2つのソリューションの違いは何ですか(まだいくつかのことを理解していないかもしれませんが、試しています):
/// <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;
}
}
私の場合、これらのソリューションはどちらも、非ブロッキング読み取りを実行し、書き込み時にのみブロッキングを実行できます...もしそうなら、どのような利点がありReaderWriterLockSlim
ますか?私がグーグルで見つけたように、Monitor
はよりはるかに速いですReaderWriterLockSlim
。もちろん、読んでいるときに辞書の状態が間違ってしまう可能性があることは理解していますが、私にとっては問題ありません。
ありがとう