lock()
// 公平锁
final void lock() {
acquire(1);
}
// 非公平锁
final void lock() {
// CAS操作,尝试将state改成1。修改成功则该线程可以成功拿到锁。(原先state为0则说明无锁)
if (compareAndSetState(0, 1))
// 设置当前线程为锁的拥有者
setExclusiveOwnerThread(Thread.currentThread());
else
// CAS没修改成功,则说明锁被占用,这是和公平锁一样,调用该方法
acquire(1);
}
acquire()
public final void acquire(int arg) {
// 1.调用tryAcquire方法获取锁资源,成功返回true,结束该方法
if (!tryAcquire(arg) &&
// 2.1 没获取到锁,执行addWaiter此方法,将没获取到锁的线程封装成Node对象,插入到AQS的队列尾部作为tail
// 2.2 调用acquireQueued方法,查看当前的Node是否排在队列前面,即(head的next),是的话尝试获取锁资源,否则挂起线程
acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
// 设置当前线程中断标志位
selfInterrupt();
}
tryAcquire()
// AQS实现,AQS是基类,这里只提供方法,具体子类实现。(用了设计模式的 模板方法)
protected boolean tryAcquire(int arg) {
throw new UnsupportedOperationException();
}
// 公平锁
protected final boolean tryAcquire(int acquires) {
// 获取当前线程
final Thread current = Thread.currentThread();
// 获取state的值
int c = getState();
// state值为0,则说明锁空闲。
if (c == 0) {
// state值为0,判断队列是否有线程在排队,如果有线程在排队,则直接结束方法,返回最外层的false
if (!hasQueuedPredecessors() &&
// 没有线程在排队,CAS操作,尝试将state改成1。修改成功则该线程可以成功拿到锁。(原先state为0则说明无锁)
compareAndSetState(0, acquires)) {
// state值为0,无线程排队,CAS操作成功,该线程可以成功拿到锁
setExclusiveOwnerThread(current);
return true;
}
}
// state值不为0,判断当前线程是否是锁的占有者
else if (current == getExclusiveOwnerThread()) {
// 是锁的占有者,state + 1
int nextc = c + acquires;
// int类型的最高位是符号位,这里判断小于0的话,则超过最大重入数,直接抛异常
if (nextc < 0)
throw new Error("Maximum lock count exceeded");
// 锁重入没有超过最大值的话,则设置锁重入数
setState(nextc);
return true;
}
return false;
}
//非公平
final boolean nonfairTryAcquire(int acquires) {
// 拿到当前线程
final Thread current = Thread.currentThread();
// 拿到state值
int c = getState();
// state为0说锁空闲,之前抢一波(不管有没有在队列里排队)
if (c == 0) {
// CAS操作,尝试将state改成1。修改成功则该线程可以成功拿到锁。(原先state为0则说明无锁)
if (compareAndSetState(0, acquires)) {
// 设置当前线程为锁的拥有者
setExclusiveOwnerThread(current);
return true;
}
}
// state不为0说明锁被占用。判断占用锁的线程是否为当前线程(是的话锁重入)
else if (current == getExclusiveOwnerThread()) {
// 锁的占有者是当前线程,则state + 1
int nextc = c + acquires;
// int类型的最高位是符号位,这里判断小于0的话,则超过最大重入数,直接抛异常
if (nextc < 0) // overflow
throw new Error("Maximum lock count exceeded");
// 锁重入没有超过最大值的话,则设置锁重入数
setState(nextc);
return true;
}
return false;
}
addWaiter()
// 将当前节点插入队列末尾,作为尾节点
private Node addWaiter(Node mode) {
// 创建当前线程为节点,mode为null则代表是互斥锁
Node node = new Node(Thread.currentThread(), mode);
// 创建对象prde指向尾节点,即pred此时是尾节点
Node pred = tail;
// 尾节点不空执行
if (pred != null) {
// 要插入的节点的前指针指向原先的尾节点
node.prev = pred;
// CAS将要插入的节点设置为尾节点
if (compareAndSetTail(pred, node)) {
// 原尾节点的后指针指向要插入的节点,返回尾节点(要插入的节点)
pred.next = node;
return node;
}
}
// 尾节点为空或者CAS失败,执行enq方法
enq(node);
return node;
}
enq()
// 循环插入节点
private Node enq(final Node node) {
for (;;) {
// 创建对象t,指向尾节点(t此时就是尾节点)
Node t = tail;
// 尾节点为空
if (t == null) {
// CAS 初始化头节点、尾节点
if (compareAndSetHead(new Node()))
tail = head;
} else {
// 尾节点不空,将要插入的节点的前指针指向原先的尾节点
node.prev = t;
// CAS将要插入的节点设置为尾节点
if (compareAndSetTail(t, node)) {
// 原尾节点的后指针指向要插入的节点,返回尾节点(要插入的节点)
t.next = node;
return t;
}
}
}
}
acquireQueued()
final boolean acquireQueued(final Node node, int arg) {
// 定义变量,失败标识为true
boolean failed = true;
try {
boolean interrupted = false;
for (;;) {
// 创建对象p为当前节点的上一个节点
final Node p = node.predecessor();
// 如果上一个节点为头节点 并且 tryAcquire方法成功获取锁资源
if (p == head && tryAcquire(arg)) {
// 设置当前节点为头节点
setHead(node);
// 上一个节点的后指针指向空(这样根可达分析算法就关联不到它,就会被当作垃圾回收)
p.next = null;
// 失败标识改为false,即获取锁成功
failed = false;
return interrupted;
}
// 如果上一个节点不是头节点 或者 tryAcquire方法没有获取到锁资源
// 判断上一个节点的状态是否正常,不正常方法结束
// CANCELLED = 1; 代表锁取消,例如tryLock()设置时间过期了
// SIGNAL = -1; 代表锁正常
// CONDITION = -2; 代表lock里面的类似wait()的作用,锁正常
// PROPAGATE = -3; 代表共享锁,锁正常
if (shouldParkAfterFailedAcquire(p, node) &&
// 上一个节点正常,将线程挂起(通过LockSupport将当前线程挂起)
parkAndCheckInterrupt())
interrupted = true;
}
} finally {
if (failed)
cancelAcquire(node);
}
}
shouldParkAfterFailedAcquire()
// 如果上一个节点不是头节点 或者 tryAcquire方法没有获取到锁资源
// 判断上一个节点的状态是否正常,不正常方法结束
// CANCELLED = 1; 代表锁取消,例如tryLock()设置时间过期了
// SIGNAL = -1; 代表锁正常
// CONDITION = -2; 代表lock里面的类似wait()的作用,锁正常
// PROPAGATE = -3; 代表共享锁,锁正常
private static boolean shouldParkAfterFailedAcquire(Node pred, Node node) {
// 获取上一个节点的状态
int ws = pred.waitStatus;
// 上一个节点状态为-1,则节点正常,返回true
if (ws == Node.SIGNAL)
return true;
// 上一个节点状态为 > 0,即只有为1,则上一个节点无效(非正常)
if (ws > 0) {
// 循环 从当前节点往前找,找到第一个正常节点,将正常节点的后指针指向当前节点
do {
node.prev = pred = pred.prev;
} while (pred.waitStatus > 0);
// 找到第一个正常节点,将正常节点的后指针指向当前节点
pred.next = node;
} else {
// 上一个节点状态 <= 0,CAS将上一个节点状态改为-1
compareAndSetWaitStatus(pred, ws, Node.SIGNAL);
}
// 上一个节点状态不正常,返回false
return false;
}
unlock()
// 释放锁
public void unlock() {
sync.release(1);
}
release()
// 判断释放锁是否成功
public final boolean release(int arg) {
// 调用tryRelease方法尝试释放锁资源
if (tryRelease(arg)) {
// 释放锁成功,创建对象指向头节点(即h为头节点)
Node h = head;
// 头节点不为空 且 头节点的状态不为0,则唤醒排队的线程
if (h != null && h.waitStatus != 0)
//
unparkSuccessor(h);
return true;
}
return false;
}
tryRelease()
// 核心方法,尝试释放锁
protected final boolean tryRelease(int releases) {
// state - 1
int c = getState() - releases;
// 当前线程 不等于 占有锁的线程,抛出异常
if (Thread.currentThread() != getExclusiveOwnerThread())
throw new IllegalMonitorStateException();
// 定义释放锁是否成功标志,默认不成功
boolean free = false;
// state = 0说明,没有重入锁了
if (c == 0) {
// 将释放锁标志置为成功
free = true;
// 将锁的占有者置为空
setExclusiveOwnerThread(null);
}
// 给state赋值
setState(c);
// 返回锁是否释放成功的标志
return free;
}
unparkSuccessor()
// 唤醒头节点
private void unparkSuccessor(Node node) {
// 获取当前节点的状态
int ws = node.waitStatus;
// 当前节点状态 < 0,即锁正常
if (ws < 0)
// CAS将节点的状态置为0 (这里对于ReentranLock来说没啥用)
compareAndSetWaitStatus(node, ws, 0);
// 创建对象指向 下一个节点
Node s = node.next;
// 下一个节点为空 或者 下一个节点的状态 > 0 则下一个节点无效(非正常)
if (s == null || s.waitStatus > 0) {
// 将下一节点置为空,即下一个节点不需要唤醒,需唤醒下一个节点的下一个节点
s = null;
// 从尾部往前遍历,找到第一个正常节点
for (Node t = tail; t != null && t != node; t = t.prev)
// 如果状态 <= 0则为正常节点
if (t.waitStatus <= 0)
s = t;
}
// 通过遍历获取到的第一个正常节点不为空,唤醒线程
if (s != null)
// 唤醒线程
LockSupport.unpark(s.thread);
}