C#多线程:使用ReaderWriterLock类实现多用户读/单用户写同步
2017-02-13 14:50
537 查看
C#多线程:使用ReaderWriterLock类实现多用户读/单用户写同步 - mile - 博客园 http://www.cnblogs.com/lhws/archive/2014/03/31/3636757.html
摘要:C#提供了System.Threading.ReaderWriterLock类以适应多用户读/单用户写的场景。该类可实现以下功能:如果资源未被写操作锁定,那么任何线程都可对该资源进行读操作锁定,并且对读操作锁数量没有限制,即多个线程可同时对该资源进行读操作锁定,以读取数据。
使用Monitor或Mutex进行同步控制的问题:由于独占访问模型不允许任何形式的并发访问,这样的效率总是不太高。许多时候,应用程序在访问资源时是进行读操作,写操作相对较少。为解决这一问题,C#提供了System.Threading.ReaderWriterLock类以适应多用户读/单用户写的场景。该类可实现以下功能:如果资源未被写操作锁定,那么任何线程都可对该资源进行读操作锁定,并且对读操作锁数量没有限制,即多个线程可同时对该资源进行读操作锁定,以读取数据。如果资源未被添加任何读或写操作锁,那么一个且仅有一个线程可对该资源添加写操作锁定,以写入数据。简单的讲就是:读操作锁是共享锁,允许多个线程同时读取数据;写操作锁是独占锁,同一时刻,仅允许一个线程进行写操作。
示例代码如下:
上例中分别创建2个读取线程和2个写入线程,交替进行读、写操作。运行结果如下图:
观察运行结果,我们很容易看出:读操作锁是共享锁,允许多个线程同时读取数据;写操作锁是独占锁,仅允许一个线程进行写操作。
如果一个线程在获取读操作锁后,进行读操作的途中,希望提升锁级别,将其变为写操作锁,可以调用ReaderWriterLock类的UpgradeToWriterLock(int timeOut)方法,该方法返回一个LockCookie值,该值保存了UpgradeToWriterLock方法调用前线程锁的状态。待写操作完成后,可调用DowngradeFromWriterLock(LockCookie lockcookie)方法,该方法根据传入的LockCookie参数值,将线程锁恢复到UpgradeToWriterLock方法调用前的状态。具体使用方法,大家可以查看MSDN以获取相关示例。
=================
拓:ReaderWriterLockSlim 这个更好
如何使用C#读写锁ReaderWriterLockSlim_C#教程_脚本之家 http://www.jb51.net/article/69869.htm
ReaderWriterLock 类 (System.Threading) https://msdn.microsoft.com/zh-cn/library/system.threading.readerwriterlock.aspx?cs-save-lang=1&cs-lang=csharp#code-snippet-1
摘要:C#提供了System.Threading.ReaderWriterLock类以适应多用户读/单用户写的场景。该类可实现以下功能:如果资源未被写操作锁定,那么任何线程都可对该资源进行读操作锁定,并且对读操作锁数量没有限制,即多个线程可同时对该资源进行读操作锁定,以读取数据。
使用Monitor或Mutex进行同步控制的问题:由于独占访问模型不允许任何形式的并发访问,这样的效率总是不太高。许多时候,应用程序在访问资源时是进行读操作,写操作相对较少。为解决这一问题,C#提供了System.Threading.ReaderWriterLock类以适应多用户读/单用户写的场景。该类可实现以下功能:如果资源未被写操作锁定,那么任何线程都可对该资源进行读操作锁定,并且对读操作锁数量没有限制,即多个线程可同时对该资源进行读操作锁定,以读取数据。如果资源未被添加任何读或写操作锁,那么一个且仅有一个线程可对该资源添加写操作锁定,以写入数据。简单的讲就是:读操作锁是共享锁,允许多个线程同时读取数据;写操作锁是独占锁,同一时刻,仅允许一个线程进行写操作。
示例代码如下:
using System; using System.Threading; namespace ProcessTest { class Program { //资源 static int theResource = 0; //读、写操作锁 static ReaderWriterLock rwl = new ReaderWriterLock(); static void Main(string[] args) { //分别创建2个读操作线程,2个写操作线程,并启动 Thread tr0 = new Thread(new ThreadStart(Read)); Thread tr1 = new Thread(new ThreadStart(Read)); Thread tr2 = new Thread(new ThreadStart(Write)); Thread tr3 = new Thread(new ThreadStart(Write)); tr0.Start(); tr1.Start(); tr2.Start(); tr3.Start(); //等待线程执行完毕 tr0.Join(); tr1.Join(); tr2.Join(); tr3.Join(); System.Console.ReadKey(); } //读数据 static void Read() { for (int i = 0; i < 3; i++) { try { //申请读操作锁,如果在1000ms内未获取读操作锁,则放弃 rwl.AcquireReaderLock(1000); Console.WriteLine("开始读取数据,theResource = {0}", theResource); Thread.Sleep(10); Console.WriteLine("读取数据结束,theResource = {0}", theResource); //释放读操作锁 rwl.ReleaseReaderLock(); } catch (ApplicationException) { //获取读操作锁失败的处理 } } } //写数据 static void Write() { for (int i = 0; i < 3; i++) { try { //申请写操作锁,如果在1000ms内未获取写操作锁,则放弃 rwl.AcquireWriterLock(1000); Console.WriteLine("开始写数据,theResource = {0}", theResource); //将theResource加1 theResource++; Thread.Sleep(100); Console.WriteLine("写数据结束,theResource = {0}", theResource); //释放写操作锁 rwl.ReleaseWriterLock(); } catch (ApplicationException) { //获取写操作锁失败 } } } } }
上例中分别创建2个读取线程和2个写入线程,交替进行读、写操作。运行结果如下图:
观察运行结果,我们很容易看出:读操作锁是共享锁,允许多个线程同时读取数据;写操作锁是独占锁,仅允许一个线程进行写操作。
如果一个线程在获取读操作锁后,进行读操作的途中,希望提升锁级别,将其变为写操作锁,可以调用ReaderWriterLock类的UpgradeToWriterLock(int timeOut)方法,该方法返回一个LockCookie值,该值保存了UpgradeToWriterLock方法调用前线程锁的状态。待写操作完成后,可调用DowngradeFromWriterLock(LockCookie lockcookie)方法,该方法根据传入的LockCookie参数值,将线程锁恢复到UpgradeToWriterLock方法调用前的状态。具体使用方法,大家可以查看MSDN以获取相关示例。
=================
拓:ReaderWriterLockSlim 这个更好
如何使用C#读写锁ReaderWriterLockSlim_C#教程_脚本之家 http://www.jb51.net/article/69869.htm
ReaderWriterLock 类 (System.Threading) https://msdn.microsoft.com/zh-cn/library/system.threading.readerwriterlock.aspx?cs-save-lang=1&cs-lang=csharp#code-snippet-1
相关文章推荐
- C#多线程:使用ReaderWriterLock类实现多用户读/单用户写同步
- C#多线程编程之使用ReaderWriterLock类实现多用户读与单用户写同步的方法
- C#多线程编程之:使用ReaderWriterLock类实现多用户读/单用户写同步
- 在win32驱动程序中使用事件实现内核层与用户层的同步
- Java多线程之~~~使用CountDownLatch来同步多个线程实现一个任务
- 使用ReaderWriterLock类实现多用户读/单用户写同步
- 2.使用synchronized关键字实现多线程的同步和互斥(不同线程同时读写同一数据)
- 多线程---使用ManualResetEvent来控制线程间的同步(实现了消费者和生产者模式)
- 多线程 : 使用 wait 和 notify 实现进程间同步通信
- 多线程---使用ManualResetEvent来控制线程间的同步(实现了消费者和生产者模式)
- 使用等待对象的方法,实现多线程的同步处理。。
- 使用HttpContext中的User属性来实现用户身份验证之用户验证票篇
- 使用HttpContext的User属性来实现用户验证
- Unix下使用Apache实现用户认证
- 在J2ME中使用Timer和TimerTask来实现多线程
- 使用Mysql的Replication功能实现数据库同步
- 使用Visual Basic 6实现真正实用的多线程处理
- Delphi中多线程用消息实现VCL数据同步显示
- 使用临界段实现优化的进程间同步对象-原理和实现
- 使用C#代码实现增加用户帐号