ESBasic 可复用的.NET类库(10) -- 简易的读

系统 1482 0

1. 缘起:

对于需要进行线程同步的地方,我们经常用的就是 .NET 内置的 lock 关键字和 ReaderWriterLock 类。 lock 的功能相对简单,因为它不区分读写,也就是说如果都在 lock 块中,读线程都会阻塞另一个读线程,在很多读远远多于写的应用中,这会极大地折损性能。所以我们也经常需要使用读写分离的锁 ReaderWriterLock ,使用它,我们可以明确的指定是要获取“读”锁还是“写”锁。而且,当前的“读”线程是不会阻塞其它的“读”线程的。

lock 的使用非常简洁,而 ReaderWriterLock 类的使用就要繁琐很多,比如像这样:

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--> private ReaderWriterLock readerWriterLock = new ReaderWriterLock ();
public void Test()
{
try
{
this .readerWriterLock.AcquireWriterLock( - 1 );
// DoSomething
}
finally
{
this .readerWriterLock.ReleaseWriterLock();
}
}


于是,我设计了 ESBasic.Threading.Synchronize.SmartRWLocker 来简化 ReaderWriterLock 的使用,使得我们可以像使用 lock 一样来使用 ReaderWriterLock

2. 适用场合:

在大多数使用 ReaderWriterLock 的地方都可以使用 SmartRWLocker 来代替,除非你需要使用某些 ReaderWriterLock 的特殊功能。 SmartRWLocker 适用于以下场合:

(1) 需要使用读写分离的锁。

(2) 不需要设置等待锁的超时时间,也就是无限期地等待锁。

(3) 不需要升级 / 降级锁,如将读锁升级为写锁,或将写锁降级为读锁。

3 .设计思想与实现

SmartRWLocker 的类图如下:

ESBasic 可复用的.NET类库(10) -- 简易的读写锁 SmartRWLocker

我们看到 SmartRWLocker 内部就是借助 ReaderWriterLock 来实现锁的控制的。而 SmartRWLocker 只有一个 Lock 方法,参数是一个 AccessMode 枚举,表示调用者是希望获取读锁还是写锁,另外该方法返回一个 LockingObject 对象。 LockingObject 的生命周期很有意思, LockingObject 对象产生的时候,就是获取锁的时刻,其被销毁的时候( Dispose 方法),就是释放锁的时刻。所以 LockingObject 对象的生命周期就是占用锁的时间段。

IDisposable 接口与 using 结合起来使用,会使得语法非常简单可读。我们可以这样来简洁地使用 SmartRWLocker

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--> private SmartRWLocker smartRWLocker = new SmartRWLocker ();
public void Test2()
{
using ( this .smartRWLocker.Lock( AccessMode .Write))
{
// DoSomething
}
}

这就非常类似 lock 的使用方式了。
最后,LastRequireReadTime和LastRequireWriteTime属性记录了最后一次获取读写锁的时间 -- 即从一个侧面记录了我们对目标资源最后一次进行读写的时间。

4. 使用时的注意事项

SmartRWLocker 简化了 ReaderWriterLock 的使用,但是正如有得必有失,它也损失了一些 ReaderWriterLock 的功能,正如在适用场合中介绍的,使用 SmartRWLocker 无法设置获取锁的超时时间,也无法升级 / 降级锁的性质。幸运的是,大多数情况下,我们都用不到这些高级一点的特性,所以, SmartRWLocker 还是有它存在的价值的。

如果你的应用需要使用 SmartRWLocker 不提供的特性,那只有转向使用 ReaderWriterLock 本身了。这也未必是个坏主意。

使用任何类型的锁的时候,你都需要注意锁的“粒度”的问题,即你的锁要锁住的范围有多大。粒度太大,会降低系统的并发;粒度太细,又会使得编程相当繁琐。所以在设计时需要进行权衡,为你的锁选择一个恰当的粒度是非常重要的。

5. 扩展

简易的读写锁 SmartRWLocker 暂时没有任何扩展。

注:ESBasic源码可到 http://esbasic.codeplex.com/ 下载。
ESBasic讨论:37677395
ESBasic开源前言

ESBasic 可复用的.NET类库(10) -- 简易的读写锁 SmartRWLocker


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论