独占式释放同步状态–release(int arg)
该方法为AQS提供的模板方法
//该方法为AQS提供的模板方法
public final boolean release(int arg) {
if (tryRelease(arg)) {//自行实现释放同步状态的方法
Node h = head;
if (h != null && h.waitStatus != 0)
//唤醒后继节点
unparkSuccessor(h);
return true;
}
return false;
}
private void unparkSuccessor(Node node) {
/*
* If status is negative (i.e., possibly needing signal) try
* to clear in anticipation of signalling. It is OK if this
* fails or if status is changed by waiting thread.
*/
int ws = node.waitStatus;
if (ws < 0)
//如果当前节点的状态小于0,就通过CAS操作尝试修改状态为0(初始状态)
compareAndSetWaitStatus(node, ws, 0);
/*
* Thread to unpark is held in successor, which is normally
* just the next node. But if cancelled or apparently null,
* traverse backwards from tail to find the actual
* non-cancelled successor.
*/
//取到节点的下一个节点
Node s = node.next;
if (s == null || s.waitStatus > 0) {
//如果为空或者已经取消/被中断
s = null;
//从尾部倒着遍历,找到离当前节点最近的节点状态小于等于0的节点(回溯)
for (Node t = tail; t != null && t != node; t = t.prev)
if (t.waitStatus <= 0)
s = t;
}
if (s != null)
//唤醒后边的节点
LockSupport.unpark(s.thread);
}