C#多线程:使用ReaderWriterLock类实现多用户读/单用户写同步

C#多线程:使用ReaderWriterLock类实现多用户读/单用户写同步 - mile - 博客园
http://www.cnblogs.com/lhws/archive/2014/03/31/3636757.html

  • 摘要: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以获取相关示例。

时间: 2024-10-05 12:59:33

C#多线程:使用ReaderWriterLock类实现多用户读/单用户写同步的相关文章

使用ReaderWriterLock类实现多用户读/单用户写同步

使用ReaderWriterLock类实现多用户读/单用户写同步[1] 2015-03-12 应用程序在访问资源时是进行读操作,写操作相对较少.为解决这一问题,C#提供了System.Threading.ReaderWriterLock类以适应多用户读/单用户写的场景. 该类可实现以下功能:如果资源未被写操作锁定,那么任何线程都可对该资源进行读操作锁定,并且对读操作锁数量没有限制,即多个线程可同时对该资源进行读操作锁定,以读取数据.如果资源未被添加任何读或写操作锁,那么一个且仅有一个线程可对该资

c++ 多个线程读一个线程写同步

这种情况一般多个线程读是不需要加锁的.就在写的时候需要加锁. 那么要做的就是让不写的时候,读不受同步限制.让多线程自由的读. 这个时候就要用读写锁 boost已经有读写锁,而c++ 14才有读写锁. std::shared_mutex write; //use boost's or c++14 // One write, no reads. void write_fun() { std::lock_guard<std::shared_mutex> lock(write); // DO WRIT

SQLSERVER 切换数据库为单用户和多用户模式

有时候数据库在占用时,想做一些操作,无法操作.可以尝试将数据库切换为单用户模式来操作.操作完之后再切换回多用户模式. 命令如下: alter database 数据库名 set Single_user  --单用户alter database 数据库名 set multi_user   --多用户 或者 sp_dboption 数据库名,"single user",true  --单用户 sp_dboption 数据库名,"single user",false  -

ReaderWriterLock类(转)

ReaderWriterLock类 通常来讲,一个类型的实例对于并行的读操作是线程安全的,但是并行地更新操作则不是(并 行地读和更新也不是). 这对于资源也是一样的,比如一个文件.当保护类型的实例安全时,使用一个简单的排它锁即解决问题,但是当有很多的读操作 而偶然的更新操作这就很不合理的限制了并发.一个例子就是这在一个业务程序服务器中,为了快速查找把数据缓存到静态字段中. 在这个方案中,ReaderWriterLock类被设计成提供最大容量的锁定. ReaderWriterLock为读和写的锁提

Java多线程01(Thread类、线程创建、线程池)

Java多线程(Thread类.线程创建.线程池) 第一章 多线程 1.1 多线程介绍 1.1.1 基本概念 进程:进程指正在运行的程序.确切的来说,当一个程序进入内存运行,即变成一个进程,进程是处于运行过程中的程序,并且具有一定独立功能. 线程:线程是进程中的一个执行单元,负责当前进程中程序的执行,一个进程中至少有一个线程.一个进程中是可以有多个线程的,这个应用程序也可以称之为多线程程序. 简而言之:一个程序运行后至少有一个进程,一个进程中可以包含多个线程 1.1.2 单线程程序 - 从入口m

【C/C++多线程编程之九】pthread读写锁

多线程编程之读写锁 Pthread是 POSIX threads 的简称,是POSIX的线程标准.  pthread读写锁把对共享资源的访问者分为读者和写者,读者只对共享资源进行读访问,写者只对共享资源进行写操作.在互斥机制,读者和写者都需要独立独占互斥量以独占共享资源,在读写锁机制下,允许同时有多个读者读访问共享资源,只有写者才需要独占资源.相比互斥机制,读写机制由于允许多个读者同时读访问共享资源,进一步提高了多线程的并发度.                   1.读写锁机制:      

多线程——继承Thread类

在具体介绍java多线程的使用之前,先让我们看看下面几个问题. 什么是多线程 简单的理解成:cpu"同时"执行多个任务,这就是多线程.(究其本质,当涉及到进程和线程的概念,上面的说法也不太合适,不过,简单的理解成这样也不为过.) 多线程解决了什么问题? 多线程通过充分利用cpu实现了提高计算机效率的问题. 使用了多线程,效率就一定会提高? 答案是否定的.在适当的情况下使用多线程,确实能提高效率,但是如果滥用多线程,有时候效率反而会降低.那么,什么情况下使用多线程会提高效率就成为了一个至

PHP CURL 多线程 GET/POST 类

PHP CURL 多线程 GET/POST 类 2015-01-01 分类:技术文章 阅读(623) 评论(0) 如果有需要更正或更高效的建议,欢迎在OSchina分享~\(≧▽≦)/~ http://www.oschina.net/code/snippet_1475115_44902 <?php /**************************************************************** PHP CURL 多线程 GET/POST Email:[email

你需要实现一个高效的缓存,它允许多个用户读,但只允许一个用户写

思路:java.util.concurrent.locks包下面ReadWriteLock接口,该接口下面的实现类ReentrantReadWriteLock维护了两个锁读锁和解锁,可用该类实现这个功能,很简单 import java.util.Date; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; /**  * 你需要实现一个