之前看了ReentrantLock独占锁和Semaphore共享锁的原理和介绍,结合这两个锁的就是ReentrantReadWriteLock读写锁。
读写锁就是:读读共享,读写互斥,写读互斥,写写互斥。
读写锁的特性:
1、支持公平与非公平锁的获取
如: public ReentrantReadWriteLock(boolean fair)//默认是非公平的
2、重进入:如:当一个读线程获取了读锁之后能够再次获取到读锁
3、锁降级:
锁降级就有必要说说了。锁降级指的是:写锁降级为读锁。指把持住当前拥有的写锁,再获取到读锁,锁喉释放写锁的过程,这时只拿了一个读锁,这个过程就是锁降级
但是:::我们看下代码:
(在图片中我说了下我的疑虑和如何实现锁降级,以及自己的分析)
那么它的内部实现是怎么实现的呢?其实也是对状态state做修改,当阻塞的时候会将被阻塞的没有拿到锁的放到同步队列中。
1、我们先说下它的原理--是如何既能保存写状态也能保存读状态的。
读写锁同样依赖于自定义同步器来实现同步功能,而读写转态就是同步器的同步状态。
我们的同步状态是一个int类型的,我们需要按位分割使用这个变量。读写锁分成两部分:高16位是读,低16位是写
设:当前状态为S
当低16位有值时,说明存在写锁。当写状态+1的时候:S+1 (存在写锁,又加1,说明是当前线程写锁重入)
当高16中不全为0时,说明存在读锁,当读状态+1的时候。高16位加1就是 1<<16,(1是低位即:0000000000000001 ,将1向左移动16位,),那么最终的S值为 S+(1<<16)
下面我们来看下源码:
写锁的获取与释放:
这里我们贴一下addWaiter和acquireQueued的源码
写锁的释放:
-------------------------------------------------------------------------------------下面我们看下读锁----------------------------------------------------------------------------------------------------------------------