• ReentrantReadWriteLock


    ReentrantReadWriteLock


    重入锁ReentrantLock是排他锁,排他锁在同一时刻仅有一个线程可以进行访问,但是在大多数场景下,大部分时间都是提供读服务,而写服务占有的时间较少。然而读服务不存在数据竞争问题,如果一个线程在读时禁止其他线程读势必会导致性能降低。所以就提供了读写锁。

    读写锁维护着一对锁,一个读锁和一个写锁。通过分离读锁和写锁,使得并发性比一般的排他锁有了较大的提升:在同一时间可以允许多个读线程同时访问,但是在写线程访问时,所有读线程和写线程都会被阻塞。

    读写锁的主要特性:

    1. 公平性:支持公平性和非公平性。
    2. 重入性:支持重入。读写锁最多支持65535个递归写入锁和65535个递归读取锁。
    3. 锁降级:遵循获取写锁、获取读锁在释放写锁的次序,写锁能够降级成为读锁

    读写锁ReentrantReadWriteLock实现接口ReadWriteLock,该接口维护了一对相关的锁,一个用于只读操作,另一个用于写入操作。只要没有 writer,读取锁可以由多个 reader 线程同时保持。写入锁是独占的。

    源码读取

    //读写锁的默认构造方法是一个非公平锁
    public ReentrantReadWriteLock() {
        this(false);
    }
    //会同时创建一个读锁和一个写锁
    public ReentrantReadWriteLock(boolean fair) {
        sync = fair ? new FairSync() : new NonfairSync();
        readerLock = new ReadLock(this);
        writerLock = new WriteLock(this);
    }
    //通过这两个方法可以获取读锁和写锁
    public ReentrantReadWriteLock.WriteLock writeLock() { return writerLock; }
    public ReentrantReadWriteLock.ReadLock  readLock()  { return readerLock; }
    
    //读写锁内部也是通过Sync继承队列同步器来实现同步
    abstract static class Sync extends AbstractQueuedSynchronizer
    

    读写锁中的方法和可重入锁大部分是一致的,只是在添加了读锁更多的实现:

    public void lock() {
        sync.acquireShared(1);
    }
    

    锁降级

    如果当前线程在获取读锁的时候发现已经有别的线程获取了写锁,则返回false,在队列中阻塞等待。如果当前线程在获取读锁的时候发现自己已经获取了写锁,则进行锁降级,降为读锁。


    参考资料:

    http://cmsblogs.com/?p=2213

  • 相关阅读:
    2019届宝鸡理数质检Ⅱ解析版
    随机事件的概率
    三视图
    求曲线的轨迹方程
    组合法破解二项式系数问题
    二项式定理
    计数原理
    HBase的Shell命令
    HBase伪分布安装
    HBase基础知识
  • 原文地址:https://www.cnblogs.com/fruitknife/p/9703119.html
Copyright © 2020-2023  润新知