1、假设有线程去获取公平锁FairLock,线程去执行lock()方法:
if (!tryAcquire(arg) &&
acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
selfInterrupt();
2、tryAcquire(1) 代码的含义:如果state为0(锁没有被线程占用)或者独占线程是当前线程时,获取锁成功,并且更改独占线程为自己,state++。
addWaiter的含义:将当前Node放在双向队列的结尾。
acquireQueued的含义:当前Node的前驱节点是不是head,如果是,当前Node(线程)尝试去获取锁,获取成功后,把它自己设置成head,返回;如果获取锁失败,进入等待(UNSAFE.park),直到被唤醒,唤醒后重复前面的过程。
selfInterrupt:如果线程有中断过,那么最后增加中断标记(被唤醒后中断标记会别清空),在执行lockInterruptibly的时候,抛出InterruptedException异常,参考AQS的acquireInterruptibly方法。
3、当head节点的线程执行完后,操作release释放锁。
public final boolean release(int arg) {
if (tryRelease(arg)) {
Node h = head;
if (h != null && h.waitStatus != 0)
unparkSuccessor(h);
return true;
}
return false;
}
4、tryRelease(1) 主要是将state–,如果state为0,独占线程设置为空。
unparkSuccessor(head) 的含义:将head的后驱节点唤醒(UNSAFE.unpark),后驱节点被唤醒后就会尝试去获取锁。
AQS的处理的最核心的方法是acquireQueued,它是通过自旋、CAS、park/unpark实现线程排队获取锁。