温馨提醒
- AbstractQueuedSynchronizer队列是CLH队列的变种,CLH队列等待采用自旋,AQS的队列等待采用LockSupport#park。
- Node.waitStatus表示对应线程是否应当阻塞,
- head节点是正占有锁的线程的,其thread值为null,处于head后驱节点的线程才会去tryAcquire,tryAcquire由子类实现。
- 入队在tail,出队在head
以下必须要子类实现:
/**
* exclusive mode
*/
boolean tryAcquire(int arg)
/**
* exclusive mode.
*/
boolean tryRelease(int arg)
/**
* shared mode.
*/
int tryAcquireShared(int arg)
/**
* shared mode.
*/
boolean tryReleaseShared(int arg)
/**
* Returns true if synchronization is held exclusively with
* respect to the current (calling) thread.
*/
boolean isHeldExclusively()
独占模式acquire
private Node enq(final Node node) {
// 无限循环,即step 1返回false(有别的线程将它的node连接到tail)也会重新将node连接到tail
for (;;) {
Node t = tail;
if (t == null) { // new一个不带任何状态的Node作为头节点
if (compareAndSetHead(new Node()))
tail = head;
} else {
node.prev = t;
if (compareAndSetTail(t, node)) { // step 1
t.next = node;
return t; // 返回当前tail
}
}
}
}
private Node addWaiter(Node mode) {
Node node = new Node(Thread.currentThread(), mode);
//-- 和#enq逻辑比,只是取消了循环,为了更快?
Node pred = tail;
if (pred != null) {
node.prev = pred;
if (compareAndSetTail(pred, node)) {
pred.next = node;
return node;
}
}
//--
enq(node);
return node; // 返回当前线程的node
}
final boolean acquireQueued(final Node node, int arg) {
boolean failed = true;
try {
boolean interrupted = false;
// 无限循环,直到当前线程node的前驱node是head,否则对于node状态为SIGNAL的线程会park
for (;;) {
final Node p = node.predecessor();
// 如果当前线程node的前驱是head
if (p == head && tryAcquire(arg)) {
// head = node; 从而让其他线程也能走入该if
// node.thread = null; 所以head永远是一个不带Thread的空节点
// node.prev = null;
setHead(node);
p.next = null; // 配合上面的 node.prev = null; for GC
failed = false;
return interrupted;
}
// 判断在tryAcquire失败后是否应该park,若是,则执行park
if (shouldParkAfterFailedAcquire(p, node) &&
// LockSupport#park,返回Thread#interrupted
parkAndCheckInterrupt())
interrupted = true;
}
} finally {
if (failed)
cancelAcquire(node);
}
}
private static boolean shouldParkAfterFailedAcquire(Node pred, Node node) {
int ws = pred.waitStatus;
// 表示当前节点应当park
if (ws == Node.SIGNAL) return true;
// 当前节点不断向前找,直到找到一个前驱节点waitStats不是CANCELLED的为止(状态值里面只有CANCELLED是大于0的)
if (ws > 0) {
do {
node.prev = pred = pred.prev;
} while (pred.waitStatus > 0);
// 中间CANCELLED的node作废
pred.next = node;
}
// 0 or PROPAGATE 需要设置为SIGNAL,但仍然返回false,即don’t park
else {
compareAndSetWaitStatus(pred, ws, Node.SIGNAL);
}
return false;
}
// Acquires in exclusive mode, ignoring interrupts
public final void acquire(int arg) {
// 这里提前tryAcquire为了省去入队列操作,提高性能,因为大部分情况下可能都没有锁竞争
if (!tryAcquire(arg) &&
// 入队列,返回当前线程中断状态
acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
selfInterrupt();
}
独占模式release
public final boolean release(int arg) {
if (tryRelease(arg)) {
Node h = head;
if (h != null && h.waitStatus != 0) // step 1
unparkSuccessor(h);
return true;
}
return false;
}
private void unparkSuccessor(Node node) {
int ws = node.waitStatus;
// 这里是SIGNAL,将head的waitStatus设为0,是为了不重复step 1
if (ws < 0)
compareAndSetWaitStatus(node, ws, 0);
Node s = node.next;
// 如果head(当前线程)无后驱node,或后驱node为CANCELLED
if (s == null || s.waitStatus > 0) {
s = null;
// 从链表tail开始遍历,取出非CANCELLED的node
for (Node t = tail; t != null && t != node; t = t.prev)
if (t.waitStatus <= 0)
s = t;
}
// 非CANCELLED的线程unpark,继续#acquireQueued的for循环
if (s != null)
LockSupport.unpark(s.thread);
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。