前言
我们都知道JUC的大多数的工具包实际是通过继承AQS(AbstractQueueSynchronizer)来实现的,在AQS中有很重要的一个属性State(int)它用来掌控线程的次序。在ReentrantLock它用来表示当前是否有线程独占|重载次数。
那么读写锁中有两个锁他是怎么依靠一个int类型来实现的呢?
高低位
我们都知道int在Java占4个字节那么表示的形式应该是
00000000 00000000 00000000 00000000
这里需要一点二进制的知识:
读写锁通过高16位来实现读锁,通过低16位实现写锁
如果高16位置出现了1就代表有读锁的存在,如果低16位出现了1就代表有写锁的存在
具体实现
这里就非常简单了
如果我们需要加锁
- 低位情况直接+1
- 高位情况直接+1再<<16
需要取数据:
- 低位直接获取
- 高位>>16在获取值
WriteLock实现(这里暂时没有考虑写锁降级读锁的问题)
- &上一个16位置全为1的值:(1<<16)-1,如果=0,再判断或者为当前线程的重入
0000为省略00000000
ReadLock实现
- 判断是否存在读锁,如果State != 0 又没有读锁那就证明现在有的是读锁