ReentrantReadWriteLock读写锁的介绍

前言:大家好,我是小威,24届毕业生,曾经在某央企公司实习,目前刚拿到某税务公司的实习offer。本篇文章将分享读写锁相关的知识点。
本篇文章记录的基础知识,适合在学Java的小白,也适合复习中,面试中的大佬
如果文章有什么需要改进的地方还请大佬不吝赐教
小威在此先感谢各位大佬啦~~
在这里插入图片描述

个人主页:小威要向诸佬学习呀
个人简介:大家好,我是小威,一个想要与大家共同进步的男人
目前状况:24届毕业生,曾经在某央企公司实习,目前在另外一家满意的公司实习

欢迎大家:这里是CSDN,我总结知识的地方,欢迎来到我的博客,我亲爱的大佬

以下正文开始

ReentrantReadWriteLock读写锁的介绍_第1张图片

读写锁简单介绍

读写锁,顾名思义,包含两种锁,一种叫做读锁,一种叫做写锁。其中读锁是共享锁,写锁是排他锁。当持有读锁时,能够对共享资源进行读操作,持有写锁时,能够对共享资源进行写操作。读锁在同一时刻允许多个线程进行读操作获取锁资源,而写锁在同一时刻只允许一个线程获取到锁资源。

由于读写锁在同一时刻能够允许多个线程同时读取共享资源,而排它锁只允许一个线程获取到锁资源,所以在高并发的情况下,读写锁性能比排它锁要好一些。
ReentrantReadWriteLock读写锁的介绍_第2张图片

读写锁源码讲解

读写锁是一个接口(ReadWriteLock),其位于java. util.concurrent.locks包下,ReadWriteLock接口中包含两个方法,分别为readLock()来获取读锁,writeLock()方法获取写锁,其源码如下:

public interface ReadWriteLock {
    Lock readLock();
    Lock writeLock();
}

ReadWriteLock读写锁接口的实现类是ReentrantReadWriteLock,在前面我们介绍过ReentranLock,他是一个支持多种方式获取锁的类,提到ReentranLock,我们在这里回顾一下Lock和synchronized的区别:

Lock和synchronized锁的区别:

synchronized本质上是关键字,而Lock锁是接口;
synchronized可以作用于方法和代码块上,而Lock锁只能作用于代码块上;
synchronized锁和Lock锁的底层不同,synchronized底层是基于objectMonitor对象锁来实现的,而Lock锁是基于AQS,FIFO先进先出队列实现的;
synchronized只支持非公平锁,而Lock锁支持公平锁和非公平锁;
synchronized是阻塞式加锁,而Lock是非阻塞式加锁,并且支持可中断式加锁,支持超时时间加锁;
synchronized在加锁和解锁时,只有一个同步队列和一个等待队列,而Lock锁有一个同步队列和支持多个等待队列(condition);
synchronized锁在进行等待和唤醒时,使用的是object类中的wait()和notify()方法,而lock锁使用的是condition接口的await()和signal()方法。

回归正题,我们来看一下ReentrantReadWriteLock实现类的源码:

    public ReentrantReadWriteLock() {
        this(false);
    }
    public ReentrantReadWriteLock(boolean fair) {
        sync = fair ? new FairSync() : new NonfairSync();
        readerLock = new ReadLock(this);
        writerLock = new WriteLock(this);
    }

ReentrantReadWriteLock支持公平锁和非公平锁的实现,可以根据fair变量使用三目运算符进行判断来创建公平锁和非公平锁,也可以使用默认创建方式,不传入参数直接创建非公平锁。

ReentrantReadWriteLock的内部实现同时依赖于内部类Sync,如下:

    private final ReentrantReadWriteLock.ReadLock readerLock;
    /** Inner class providing writelock */
    private final ReentrantReadWriteLock.WriteLock writerLock;
    /** Performs all synchronization mechanics */
    final Sync sync;

ReentrantReadWriteLock读写锁的介绍_第3张图片
我们点入Sync类查看源码可以看到,Sync是继承了AbstractQueuedSynchronizer的,因此ReentrantReadWriteLock实现类仍然依赖于AQS来实现。

ReentrantReadWriteLock读写锁的介绍_第4张图片
在ReentrantReadWriteLock中实现读锁和写锁,需要维护一个读状态和写状态,在ReentrantReadWriteLock中,使用state高16位表示读状态(获取读锁的次数),使用state的低16位表示获取到写锁的线程的可重入的次数。

       static final int SHARED_SHIFT   = 16;
        static final int SHARED_UNIT    = (1 << SHARED_SHIFT);
        static final int MAX_COUNT      = (1 << SHARED_SHIFT) - 1;
        static final int EXCLUSIVE_MASK = (1 << SHARED_SHIFT) - 1;

        /** Returns the number of shared holds represented in count  */
        static int sharedCount(int c)    { return c >>> SHARED_SHIFT; }
        /** Returns the number of exclusive holds represented in count  */
        static int exclusiveCount(int c) { return c & EXCLUSIVE_MASK; }

由于篇幅原因,本篇文章就先分享到这里了,后续会分享读写锁加锁和释放锁流程的知识,感谢大佬认真读完支持咯~
在这里插入图片描述

文章到这里就结束了,如果有什么疑问的地方请指出,诸佬们一起讨论
希望能和诸佬们一起努力,今后进入到心仪的公司
再次感谢各位小伙伴儿们的支持

在这里插入图片描述

你可能感兴趣的:(java,jvm,lock)