天天看点

《C#多线程编程实战(原书第2版)》——2.9 使用ReaderWriterLockSlim类

本节书摘来自华章出版社《c#多线程编程实战(原书第2版)》一书中的第2章,第2.9节,作者(美)易格恩·阿格佛温(eugene agafonov),黄博文 黄辉兰 译,更多章节内容可以访问云栖社区“华章计算机”公众号查看。

本节将描述如何使用readerwriterlockslim来创建一个线程安全的机制,在多线程中对一个集合进行读写操作。readerwriterlockslim代表了一个管理资源访问的锁,允许多个线程同时读取,以及独占写。

为了学习本节,你需要安装visual studio 2015。除此之外无需其他准备。

本节的源代码放置在booksampleschapter2recipe8目录中。

请执行以下步骤来了解如何使用readerwriterlockslim类来创建一个线程安全的机制,在多线程中对集合进行读写操作:

1.启动visual studio 2015。新建一个c#控制台应用程序项目。

2.在program.cs文件中加入以下using指令:

《C#多线程编程实战(原书第2版)》——2.9 使用ReaderWriterLockSlim类

3.在main方法下面加入以下代码片段:

《C#多线程编程实战(原书第2版)》——2.9 使用ReaderWriterLockSlim类
《C#多线程编程实战(原书第2版)》——2.9 使用ReaderWriterLockSlim类
《C#多线程编程实战(原书第2版)》——2.9 使用ReaderWriterLockSlim类

4.在main方法中加入以下代码片段:

《C#多线程编程实战(原书第2版)》——2.9 使用ReaderWriterLockSlim类
《C#多线程编程实战(原书第2版)》——2.9 使用ReaderWriterLockSlim类

5.运行程序。

当主程序启动时,同时运行了三个线程来从字典中读取数据,还有另外两个线程向该字典中写入数据。我们使用readerwriterlockslim类来实现线程安全,该类专为这样的场景而设计。

这里使用两种锁:读锁允许多线程读取数据,写锁在被释放前会阻塞了其他线程的所有操作。获取读锁时还有一个有意思的场景,即从集合中读取数据时,根据当前数据而决定是否获取一个写锁并修改该集合。一旦得到写锁,会阻止阅读者读取数据,从而浪费大量的时间,因此获取写锁后集合会处于阻塞状态。为了最小化阻塞浪费的时间,可以使用enterupgradeablereadlock和exitupgradeablereadlock方法。先获取读锁后读取数据。如果发现必须修改底层集合,只需使用enterwritelock方法升级锁,然后快速执行一次写操作,最后使用exitwritelock释放写锁。

在本例中,我们先生成一个随机数。然后获取读锁并检查该数是否存在于字典的键集合中。如果不存在,将读锁更新为写锁然后将该新键加入到字典中。始终使用try/finally代码块来确保在捕获锁后一定会释放锁,这是一项好的实践。

所有的线程都被创建为后台线程。主线程在所有后台线程完成后会等待30秒。