ReentrantReadWriteLock之写锁释放流程
流程概述:
- 判断当前线程是否持有锁,如果不持有,抛出异常
- 将state值-1,判断state值是否为0
- 如果不为0,锁释放流程结束
- 如果为0,判断head节点的waitStatus值是否为0
- 如果不为0,说明有待唤醒的节点
- 将head的waitStatus值设置为0,判断head的next节点是否是有效节点
- 如果不是,从AQS链表的最后一个节点开始往前找,寻找到离head节点最近的节点
- 然后唤醒此节点
public void unlock() {
sync.release(1);
}
public final boolean release(int arg) {
if (tryRelease(arg)) {
Node h = head;
if (h != null && h.waitStatus != 0)
unparkSuccessor(h);
return true;
}
return false;
}
protected final boolean tryRelease(int releases) {
// 判断当前线程是否持有锁
if (!isHeldExclusively())
// 当前线程不持有锁
throw new IllegalMonitorStateException();
// state值-1,释放锁资源
int nextc = getState() - releases;
// 判断state值-1后,低16位是否为0
boolean free = exclusiveCount(nextc) == 0;
if (free)
// 如果state值-1后低16位为0,设置当前持有锁资源的线程为null
setExclusiveOwnerThread(null);
setState(nextc);
return free;
}
private void unparkSuccessor(Node node) {
int ws = node.waitStatus;
if (ws < 0)
compareAndSetWaitStatus(node, ws, 0);
Node s = node.next;
if (s == null || s.waitStatus > 0) {
s = null;
for (Node t = tail; t != null && t != node; t = t.prev)
if (t.waitStatus <= 0)
s = t;
}
if (s != null)
LockSupport.unpark(s.thread);
}