zoukankan      html  css  js  c++  java
  • ReadWriteLock与ReentrantReadWriteLock

          JAVA的JUC包中的锁包括"独占锁"和"共享锁"。JUC中的共享锁有:CountDownLatch、CyclicBarrier、Semaphore、ReentrantReadWriteLock等。本章会以ReentrantReadWriteLock为蓝本对共享锁进行说明。

    一、ReentrantLock与ReentrantReadWriteLock

        说到ReentrantReadWriteLock,首先要做的是与ReentrantLock划清界限。它和后者都是单独的实现,彼此之间没有继承或实现的关系。

    ReentrantLock 实现了标准的互斥操作,也就是一次只能有一个线程持有锁,也即所谓独占锁的概念。显然这个特点在一定程度上面减低了吞吐量,实际上独占锁是一种保守的锁策略,在这种情况下任何“读/读”,“写/读”,“写/写”操作都不能同时发生。但是同样需要强调的一个概念是,锁是有一定的开销的,当并发比较大的时候,锁的开销就比较客观了。所以如果可能的话就尽量少用锁,非要用锁的话就尝试看能否改造为读写锁。

    ReadWriteLock 描述的是:一个资源能够被多个读线程访问,或者被一个写线程访问,但是不能同时存在读写线程。也就是说读写锁使用的场合是一个共享资源被大量读取操作,而只有少量的写操作(修改数据)。

    参考:http://my.oschina.net/adan1/blog/158107?fromerr=M4d1zh4s

    二、ReadWriteLock 和 ReentrantReadWriteLock

         ReadWriteLock,顾名思义,是读写锁。它维护了一对相关的锁 — — "读取锁"和"写入锁",一个用于读取操作,另一个用于写入操作。     

        "读取锁"用于只读操作,它是"共享锁",能同时被多个线程获取。     

        "写入锁"用于写入操作,它是"独占锁",写入锁只能被一个线程锁获取。 注意:不能同时存在读取锁和写入锁!

         ReadWriteLock是一个接口。ReentrantReadWriteLock是它的实现类,ReentrantReadWriteLock包括子类ReadLock和WriteLock。

     

    ReentrantReadWriteLock的UML类图如下:

           读写锁的机制:"读-读"不互斥、"读-写"互斥、"写-写"互斥。即在任何时候:只有一个线程在写入;线程正在读取的时候,写入操作等待;线程正在写入的时候,其他线程的写入操作和读取操作都要等待;

    读锁的加锁源代码片段如下:

    写锁的加锁源代码片段下:

    相比较而言,就是上面说过的一旦写锁加锁时发现有其他线程进行了操作,则将当前线程放置于线程等待队列中——之后再唤醒。而读操作锁直接进行了共享线程,并发读取。 

    锁降级:从写锁变成读锁;锁升级:从读锁变成写锁。读锁是可以被多线程共享的,写锁是单线程独占的。也就是说写锁的并发限制比读锁高,这可能就是升级/降级名称的来源。

    如下代码会产生死锁,因为同一个线程中,在没有释放读锁的情况下,就去申请写锁,这属于锁升级,ReentrantReadWriteLock是不支持的。

                ReadWriteLock rtLock = new ReentrantReadWriteLock();  

                rtLock.readLock().lock();  

                System.out.println("get readLock.");  

                rtLock.writeLock().lock();  

                System.out.println("blocking");  

                ReadWriteLock rtLock = new ReentrantReadWriteLock();

                rtLock.readLock().lock();
                System.out.println("get readLock.");
                rtLock.writeLock().lock();
                System.out.println("blocking");

    ReentrantReadWriteLock支持锁降级,如下代码不会产生死锁。

                ReadWriteLock rtLock = new ReentrantReadWriteLock();  

                rtLock.writeLock().lock();  

                System.out.println("writeLock");  

                rtLock.readLock().lock();  

                System.out.println("get read lock");   

  • 相关阅读:
    系统提供的列表框的选择菜单
    symbian 下 xml 的操作总结
    在3版中实现并动态配置开机自启动
    Symbian (Read Inbox)读取收件箱的内容
    S60平台:使用外部应用程序View
    手机通讯录助手s60 第三版与 s60第五版可用 诺基亚手机
    关于静默安装需要注意的一些问题(转)
    关于自定义控件捕获 EButton1Up 事件
    javascript简单区分现代浏览器和ie6,7,8
    301、404、200、304等HTTP状态
  • 原文地址:https://www.cnblogs.com/moonandstar08/p/5107705.html
Copyright © 2011-2022 走看看