PS: AQS全称AbstractQueueSynchronizer,抽象队列同步器,是并发中最核心的一个类了,本篇文章不剖析源码,只用文字和图形表达。
通过看源码可知,ReentranctLock
关于锁的操作,都是基于AQS的。
AQS中有两个核心的属性,状态变量state
和双向链表head
和tail
。
state
用于保存当前是否有锁以及锁的种类(读or写),默认值为0,通过VarHandle.compareAndSet(this, expect, update)
,来改变字段值(这个就是传说中的CAS操作,基于底层操作系统,能保证原子性)。JDK开发人员也巧妙地将int类型的state
的高低16位,分别代表锁的读和写,从而能让一个参数,存储到读和写两个状态.
双向链表head
和tail
,用于将阻塞的线程加入到队尾中,然后从队首取出阻塞的线程进行消费。
其实跟ReentrantLock
类似,只是ReentrantReadWriteLock
有ReadLock
和WriteLock
两把锁。说是两把锁,但是两个对象,都是使用的AQS
中的锁,也就是通过state
变量控制读写锁状态,并且通过AQS里内部算法实现:读写锁互斥,写写锁互斥,读读锁正常取值。