1 释放锁
1.1 释放锁基本流程
1.2 释放锁源码分析
无论是公平锁还是非公平锁,都是执行release()方法
public void unlock() {
sync.release(1);
}
public final boolean release(int arg) {
// 如果当前是重入锁,假设state=2,那么释放失败,就不需要唤醒下面线程了
if (tryRelease(arg)) {
// 释放锁成功
Node h = head;
// 代表后面还有排队的,等着你去唤醒了
// h状态不为空。即为-1
if (h != null && h.waitStatus != 0)
unparkSuccessor(h);
return true;
}
return false;
}
protected final boolean tryRelease(int releases) {
// realse 1
// 拿到state - 1(并没有赋值给state)
int c = getState() - releases;
// 当前持有锁资源不是当前资源抛异常
if (Thread.currentThread() != getExclusiveOwnerThread())
throw new IllegalMonitorStateException();
// false 代表是否释放干净
boolean free = false;
//
if (c == 0) {
free = true;
setExclusiveOwnerThread(null);
}
setState(c);
// 锁资源释放干净返回true,否则返回false
return free;
}
// 唤醒后面排队的Node
private void unparkSuccessor(Node node) {
// 拿到头节点状态
int ws = node.waitStatus;
if (ws < 0)
// 先基于CAS,将节点状态从-1,改为0
compareAndSetWaitStatus(node, ws, 0);
// 拿到头节点的后续节点。
Node s = node.next;
// 如果后续节点为null或者,后续节点的状态为1,代表节点取消了。
if (s == null || s.waitStatus > 0) {
s = null;