This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public final void acquire(int arg) { | |
if (!tryAcquire(arg) && | |
//尝试获取锁,失败则为当前线程创建节点并入队等待。arg也会被保存在节点内 | |
acquireQueued(addWaiter(Node.EXCLUSIVE), arg)) //等待排他权限 | |
selfInterrupt(); //1. 不清楚这里为什么要中断一下当前线程? | |
} | |
// 为当前线程创建排他/共享模式的节点并加入节点队列 | |
private Node addWaiter(Node mode) { | |
// 为当前线程创建一个Node实例 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
private Node enq(final Node node) { | |
for (;;) { //若CAS失败则反复重试,直到CAS成功后才返回 | |
Node t = tail; | |
if (t == null) { // Must initialize | |
if (compareAndSetHead(new Node())) //CAS初始化头节点 | |
tail = head; | |
} else { | |
//连接前驱节点 | |
node.prev = t; | |
if (compareAndSetTail(t, node)){ //CAS更新尾节点为新插入节点 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
final boolean acquireQueued(final Node node, int arg) { | |
boolean failed = true; | |
try { | |
boolean interrupted = false; | |
for (;;) { | |
// 获取当前线程对应节点的前驱节点 | |
final Node p = node.predecessor(); | |
if (p == head && tryAcquire(arg)) { | |
// 当前节点位于队首,则重新尝试获取锁, | |
// 获取锁成功则将本节点出队并设为head |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Checks and updates status for a node that failed to acquire. | |
* Returns true if thread should block. This is the main signal | |
* control in all acquire loops. Requires that pred == node.prev. | |
* | |
* @param pred node's predecessor holding status | |
* @param node the node | |
* @return {@code true} if thread should block | |
*/ | |
private static boolean shouldParkAfterFailedAcquire(Node pred, Node node) { |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
private void cancelAcquire(Node node) { | |
// Ignore if node doesn't exist | |
if (node == null) | |
return; | |
node.thread = null; // 清理节点中线程的引用 | |
// Skip cancelled predecessors | |
// 跳过前方已取消的节点 | |
Node pred = node.prev; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Sets head of queue, and checks if successor may be waiting | |
* in shared mode, if so propagating if either propagate > 0 or | |
* PROPAGATE status was set. | |
* | |
* @param node the node | |
* @param propagate the return value from a tryAcquireShared | |
*/ | |
private void setHeadAndPropagate(Node node, int propagate) { | |
Node h = head; // Record old head for check below |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
final boolean nonfairTryAcquire(int acquires) { | |
final Thread current = Thread.currentThread(); | |
int c = getState(); | |
if (c == 0) { // 0 表示锁可用 | |
if (compareAndSetState(0, acquires)) { // CAS获取相应数量的锁 | |
setExclusiveOwnerThread(current); // 记录当前线程为占用排他锁的线程,用以让该线程可以重入地再次获取 | |
return true; | |
} | |
} | |
else if (current == getExclusiveOwnerThread()) { // 允许占有排他锁的线程重入 |
OlderNewer