(三)J.U.C之locks框架:ReentrantReadWriteLock

一、ReentrantReadWriteLock类简介

ReentrantReadWriteLock类,顾名思义,是一种读写锁,它是ReadWriteLock接口的直接实现,该类在内部实现了具体独占锁特点的写锁,以及具有共享锁特点的读锁,和ReentrantLock一样,ReentrantReadWriteLock类也是通过定义内部类实现AQS框架的API来实现独占/共享的功能。

 

ReentrantReadWriteLock类具有如下特点:

 

1.1支持公平/非公平策略

与ReadWriteLock类一样,ReentrantReadWriteLock对象在构造时,可以传入参数指定是公平锁还是非公平锁。

 

1.2支持锁重入

  • 同一读线程在获取了读锁后还可以获取读锁。
  • 同一写线程在获取了写锁之后既可以再次获取写锁又可以获取读锁。

 

1.3支持锁降级

所谓锁降级,就是:先获取写锁,然后获取读锁,最后释放写锁,这样写锁就降级成了读锁。但是,读锁不能升级成写锁。简言之,就是:

写锁可以降级成读锁,读锁不能升级成写锁。

 

1.4Condition条件支持

ReentrantReadWriteLock的内部读锁类、写锁类实现了Lock接口,所以可以通过newCondition()方法获取Condition对象。但是这样要注意,读锁是没法获取Condition对象的,读锁调用newCondition()方法会直接抛出UnsupportedOperationException

我们知道,condition的作用其实是对Object类的wait()notify()的增强,是为了让线程在指定对象上等待,是一种线程之间进行协调的工具。

当线程调用condition对象的await方法时,必须拿到和这个condition对象关联的锁。由于线程对读锁的访问是不受限制的(在写锁未被占用的情况下),那么即使拿到了和读锁关联的condition对象也是没有意义的,因为读线程之间不需要进行协调。



1.5使用示例

以下是Oracle官方给出的一个例子:

使用ReentrantReadWriteLock控制对TreeMap的访问(利用读锁控制读操作的访问,利用写锁控制修改操作的访问),将TreeMap包装成一个线程安全的集合,并且利用了读写锁的特性来提高并发访问。

 

public class RWTreeMap {
    private final Map<String,Object> m = new TreeMap<String,Object>();
    private final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
    private final Lock r = rwl.readLock();
    private final Lock w = rwl.writeLock();

    public Object get(String key){
        r.lock();
        try {
            return m.get(key);
        }finally{
            r.unlock();
        }
    }

    public String[] allKeys(){
        r.lock();
        try {
            return (String[]) m.keySet().toArray();
        }finally {
            r.unlock();
        }
    }

    public Object put(String key,Object value){
        w.lock();
        try {
            return m.put(key, value);
        }finally{
            w.unlock();
        }
    }

    public void clear(){
        w.lock();
        try {
            m.clear();
        }finally {
            w.unlock();
        }
    }
}

 

 

 

二、ReentrantReadWriteLock类/方法声明

2.1类声明

内部嵌套类声明:

ReentrantReadWriteLock类有两个内部嵌套类ReadLockWriteLock,这两个内部类的实例会在ReentrantReadWriteLock类的构造器中创建,并通过ReentrantReadWriteLock类的readLock()writeLock()方法访问。

 

 

2.2方法声明

ReentrantReadWriteLock类的核心方法其实就两个:readLock()和writeLock(),其它都是一些用来监控系统状态的方法,返回的都是某一时刻点的近似值。

 

 

 

借鉴学习自https://segmentfault.com/a/1190000015562389

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值