/**
* Releases in exclusive mode. Implemented by unblocking one or
* more threads if {@link #tryRelease} returns true.
* This method can be used to implement method {@link Lock#unlock}.
*
* @param arg the release argument. This value is conveyed to
* {@link #tryRelease} but is otherwise uninterpreted and
* can represent anything you like.
* @return the value returned from {@link #tryRelease}
*/
public final boolean release(int arg) {
if (tryRelease(arg)) {
Node h = head;
if (h != null && h.waitStatus != 0)
unparkSuccessor(h);
return true;
}
return false;
}1. 尝试释放状态<br/>
如果tryRelease成功,判断当前头结点的状态,如果头结点不为null,而且状态不是0(已经被初始化过),进行unpark操作。
这说明头结点的后继节点正在等待获取该锁。之前该后继节点在尝试获取锁的时候,将其前驱节点的状态改为了SIGNAL。
2.{@link java.util.concurrent.locks.AbstractQueuedSynchronizer#unparkSuccessor}<br/>获取当前节点的后继节点,如果满足状态,那么进行唤醒操作,如果没有满足状态(比如被取消),从尾部开始找寻符合要求的节点并将其唤醒
/**
* Wakes up node's successor, if one exists.
*
* @param node the node
*/
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)
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;
for (Node t = tail; t != null && t != node; t = t.prev)
if (t.waitStatus <= 0)
s = t;
}
if (s != null)
LockSupport.unpark(s.thread);
}3. 唤醒当前节点的后继节点所包含的线程<br/>
通过LockSupport的unpark方法将休眠中的线程唤醒,让其继续在acquireQueued等自旋等待锁的方法中acquire锁(状态)。
本文详细解析了Java并发框架中AbstractQueuedSynchronizer类的release方法工作原理,包括尝试释放状态、唤醒后继线程的具体实现过程,并介绍了LockSupport.unpark方法的作用。
661

被折叠的 条评论
为什么被折叠?



