- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
编辑: 从我已经得到的答案来看,我了解到我提出的第一个解决方案并不是真正的“不阻塞读取”,因为只有一个线程可以进入可升级锁而写锁不能在阅读发布之前采取...
所以我的问题是,如果不存在,如何以正确的方式使第一个解决方案成为“非阻塞读取”并创建?
我正在尝试了解非阻塞多线程读取的两种解决方案。以下两种解决方案之间有什么区别(也许我仍然不明白某些事情,但我正在尝试):
/// <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
有什么好处?正如我在 google 中发现的那样,Monitor
比 ReaderWriterLockSlim
快得多。我当然知道我在阅读时可能会得到不正确的字典状态,但这对我来说没关系。
谢谢
最佳答案
Only one thread can enter upgradeable mode at any given time
基本上,您并没有比使用完全锁做得更好 - 除了 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
}
关于c# - ReaderWriterLockSlim 与双锁检查模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14215502/
有很多关于 ReaderWriterLockSlim 类的文章,它允许多次读取和一次写入。所有这些(至少我发现的)都告诉了如何使用它,而没有太多解释它为什么以及如何工作。标准代码示例是: lock.E
我对 ReaderWriterLockSlim 和延迟 ExitWriteLock 感到沮丧。为什么定时器回调中会释放WriteLock? var _lock = new ReaderWriterLo
我围绕 ReaderWriterLockSlim 编写了一个相当简单的包装器: class SimpleReaderWriterLock { private class Guard : IDi
编辑: 从我已经得到的答案来看,我了解到我提出的第一个解决方案并不是真正的“不阻塞读取”,因为只有一个线程可以进入可升级锁而写锁不能在阅读发布之前采取... 所以我的问题是,如果不存在,如何以正确的方
我正在为在 Windows Azure 中运行的应用程序编写全局错误处理程序/记录器。当应用程序中发生错误时,会执行许多需要自动发生的操作。我需要防止在前一个错误完成之前记录错误。同时,我希望根据需要
我正在编写一个广泛使用多线程的应用程序。一些线程使用 ReaderWriterLockSlim 共享一个 observablecollection。 我有时会遇到死锁,我需要知道在死锁发生时哪个线程持
我有一节课使用 ReaderWriterLockSlim具有一个读取方法和一个写入方法,该方法使用读取方法检索要修改的元素。一个简单的例子是: class FooLocker { Reader
我遇到了这个异常 正在释放读锁而不被持有。 在 System.Threading.ReaderWriterLockSlim.ExitReadLock() 在 .. GetBreed(字符串) 下面是代
我一直在研究集合和线程,并发现了人们创建的漂亮的扩展方法,它们通过允许 IDisposable 模式来简化 ReaderWriterLockSlim 的使用。 但是,我相信我已经意识到实现中的某些东西
我正在使用这段代码在 ReaderWriterLock 上做一个非常愚蠢的基准测试,其中读取的频率是写入的 4 倍: class Program { static void Main()
目前我正在使用 WinDbg 分析转储。 我运行了以下命令(遵循 Tess' incredible walkthrough ): ~* e !clrstack 其中列出了所有线程的所有堆栈。有 300
我正在使用 ReaderWriterLockSlim保护一些操作。我想偏爱读者而不是作者,这样当读者长时间持有锁并且作者试图获取写锁时,进一步的读者不会被作者的尝试阻塞(如果作者在 lock.Ente
Based on Microsoft documentation EnterReadLock 用于在读取模式下锁定。它还表示多个线程可以读取,但一次只能有一个线程写入。 为什么我们应该使用 Enter
我想检查以下代码是否可以抵抗 ThreadAbortException 并且不会导致孤儿锁。如果不是,避免孤儿锁的最佳模式是什么? ReaderWriterLockSlim _lock = new R
我正在使用 ConcurrentBag 在运行时存储对象。在某些时候,我需要清空包并将包中的内容存储到列表中。这就是我所做的: IList list = new List();
我正在调试针对 .NET 3.5 的托管应用程序中的挂起。其中一个线程永远等待方法 System.Threading.ReaderWriterLockSlim.EnterWriteLock。为了找出哪
是否有等效的 Monitor.Pulse 和 Monitor.Wait 可以与 ReaderWriterLockSlim 结合使用? 我有一个类,其中封装了对底层队列的多线程访问。为了对某些东西进行排
我正在尝试实现许多利用 ReaderWriterLockSlim 实现线程安全的属性。所以像大多数人一样,我最终在我的所有属性中都有这样的东西: public string Name { ge
我有一个类 MyClass。此类有一个字段:public ReaderWriterLockSlim rw;(public 用于更简单的示例代码)。许多线程可以使用 rw.EnterReadLock 等
我一直在使用 ReaderWriterLockSlim一段时间以来,它已经满足了我的需求。当我继续微调我的应用程序时,我发现 ReaderWriterLockSlim 对于我的用例来说略显次优。 根据
我是一名优秀的程序员,十分优秀!