判断state值是否等于0,如果等于0,
说明当前还没有线程获取锁对象资源。
compareAndSetState(0, 1):将state值改为1,
setExclusiveOwnerThread:将当前线程设置为排它线程,其它线程获取锁资源需要等待
acquire(arg) {
if (!tryAcquire(arg) && acquireQueued(
addWaiter(Node.EXCLUSIVE), arg))
selfInterrupt();
}
tryAcquire:
1、判断当前state值是否为0,若是,则并把当前线程设置为排它线程并直接给当前线程放行,
2、判断当前线程是否和排它线程是同一个线程,若是,则将state值进行累加并直接给当前线程放行
1、判断tail节点是否为空
Node pred = tail;
若不为空,则将新加入的node.prev指向pred,再将tail节点改为node节点,最后将pred.next指向node节点
若为空,则执行enq方法(自旋)
第一次:
tail为空:
创建一个新节点作为哨兵节点node
将head节点指向node,然后将
tail节点指向head。
第二次:
tail不为空:
Node t = tail;
将node.prev指向t,
将tail指向node,
最后将t.next指向node
1、先获取当前节点的前序节点:Node p = node.predecessor(),
若p==head且tryAcquire(arg)为true时,
将当前节点作为head节点,且p.next=null(GC回收)
若不满足,则继续执行:shouldParkAfterFailedAcquire(p, node) &&
parkAndCheckInterrupt()
final Node p=node.predecessor();
if (p == head && tryAcquire(arg)) {
setHead(node);
p.next = null; // help GC
failed = false;
return interrupted;
}
一、shouldParkAfterFailedAcquire
1、判断Node的waitStatus状态,
将pred节点的waitStatus设置为Node.SIGNAL对应值,用于指示线程执行unpark操作
二、parkAndCheckInterrupt
1、LockSupport.park(this);
将当前线程进行阻塞
1、判断当前线程是否是获取锁的排它线程,若不是则抛出异常:IllegalMonitorStateException
2、判断state值是否为0,若等于0则将排它线程置为null
3、更新state状态值
一、判断head节点是否为空且waitStatus值是否为0,满足条件:
1、将该节点的waitStatus值重置为0
2、获取下一个节点,若下一个节点s不为空,
则执行LockSupport.unpark(s.thread);
从此唤醒s节点的线程。让它尝试继续获取锁操作