ReentrantReadWriteLock读写锁实现详解

54 阅读1分钟

前言

我们都知道JUC的大多数的工具包实际是通过继承AQS(AbstractQueueSynchronizer)来实现的,在AQS中有很重要的一个属性State(int)它用来掌控线程的次序。在ReentrantLock它用来表示当前是否有线程独占|重载次数。

那么读写锁中有两个锁他是怎么依靠一个int类型来实现的呢?

高低位

我们都知道int在Java占4个字节那么表示的形式应该是

00000000 00000000 00000000 00000000

这里需要一点二进制的知识:

读写锁通过高16位来实现读锁,通过低16位实现写锁

image.png

如果高16位置出现了1就代表有读锁的存在,如果低16位出现了1就代表有写锁的存在

具体实现

这里就非常简单了

如果我们需要加锁

  • 低位情况直接+1
  • 高位情况直接+1再<<16

需要取数据:

  • 低位直接获取
  • 高位>>16在获取值

WriteLock实现(这里暂时没有考虑写锁降级读锁的问题)

  • &上一个16位置全为1的值:(1<<16)-1,如果=0,再判断或者为当前线程的重入

0000为省略00000000 image.png ReadLock实现

  • 判断是否存在读锁,如果State != 0 又没有读锁那就证明现在有的是读锁

image.png