AbstractQueuedSynchronizer(抽象队列同步器)
以下拿ReentrantLock源码来分析。
ReentrantLock是一个排它锁,可重入锁
Sync这里是一个内部抽象类,分别有2个实现:FairSync(公平锁)
NoFairSync(非公平锁)
FairSync的加锁流程:
1.空壳方法传入1,其实是为了以后cas操作。
2.
先去尝试获取锁。
getState()这个方法是获取锁的状态,注意此成员变量是加了volatile所以线程内部是可见的。
c==0表示当前没有线程持有锁,所以我们要进行第一次hasQueuedPredecessors是否要进行排队。
这里会分为3种情况:
h != t
1.此时AQS队列为null,还未初始化,所以他们不相等
2.初始化AQS队列,默认我们的AQS队列至少有两个Node节点,
这是为什么呢?因为大神认为我们的第一个节点是不需要排队的,就好比我们去火车站买票,当前排队处理业务的人,是不需要等待的,除非是当前队列中只有最后一个节点。
根据图上说明此时的h != t成立,
所以要进行后面的判断这里要说明下为什么要取h.next,为什么?为什么?
因为第一个node节点Doug Lea认为是不需要参与排队的,因为第一个队列就是默认现在持有锁的队列,
s = h.next) == null
什么时候会等于null呢?
只有当前节点为末尾节点此时next就会为null
3.下面我们来看下 compareAndSetState(0, acquires)
这个是一个cpu的原子操作,根据位移偏移量来实现。
4.添加node节点的一个方法
此方法是自旋。
t==null
此时AQS队列没有初始化,设置head和tail为当前node节点,结束本次循环,第二次进来, node.prev = t;
t代表我们刚才创建的上一个node节点, t.next = node;则为我们传入的节点。