Skip to content

Commit c26a7ed

Browse files
committed
add:一些AQS 细节
1 parent 102dfc8 commit c26a7ed

File tree

2 files changed

+36
-21
lines changed

2 files changed

+36
-21
lines changed

src/java/util/concurrent/locks/AbstractQueuedSynchronizer.java

Lines changed: 23 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -326,7 +326,7 @@ static final class Node {
326326
/**
327327
* 状态字段,仅采用以下值:
328328
* SIGNAL:
329-
* 此节点的后继者被(或将很快被)阻止(通过停放),因此当前节点在释放或取消时必须取消其后继者的停放。
329+
* 此节点的后继者被(或将很快被)阻塞(通过park方法),因此当前节点在释放或取消时必须取消其后继者的停放。
330330
* 为避免种族冲突,acquire方法必须首先指示它们需要信号,然后重试原子获取,然后在失败时阻塞。
331331
* CANCELLED:
332332
* 由于超时或中断,该节点被取消。
@@ -482,17 +482,20 @@ protected final boolean compareAndSetState(int expect, int update) {
482482
static final long spinForTimeoutThreshold = 1000L;
483483

484484
/**
485-
* Inserts node into queue, initializing if necessary. See picture above.
485+
* 将节点插入队列,必要时进行初始化。
486486
* @param node the node to insert
487487
* @return node's predecessor
488488
*/
489489
private Node enq(final Node node) {
490490
for (;;) {
491491
Node t = tail;
492+
//若没有初始化则初始化操作
492493
if (t == null) { // Must initialize
494+
//CAS抢夺一下,失败重新来过
493495
if (compareAndSetHead(new Node()))
494496
tail = head;
495497
} else {
498+
//抢尾部
496499
node.prev = t;
497500
if (compareAndSetTail(t, node)) {
498501
t.next = node;
@@ -514,6 +517,7 @@ private Node addWaiter(Node mode) {
514517
Node pred = tail;
515518
if (pred != null) {
516519
node.prev = pred;
520+
//尝试一次,失败说明有人在竞争锁,降级进入enq进行争夺
517521
if (compareAndSetTail(pred, node)) {
518522
pred.next = node;
519523
return node;
@@ -570,9 +574,8 @@ private void unparkSuccessor(Node node) {
570574
}
571575

572576
/**
573-
* Release action for shared mode -- signals successor and ensures
574-
* propagation. (Note: For exclusive mode, release just amounts
575-
* to calling unparkSuccessor of head if it needs signal.)
577+
* 共享模式下的释放动作-信号后继并确保传播。
578+
* (注意:对于独占模式,如果需要信号,释放仅相当于调用head的unparkSuccessor。)
576579
*/
577580
private void doReleaseShared() {
578581
/*
@@ -616,20 +619,16 @@ private void setHeadAndPropagate(Node node, int propagate) {
616619
Node h = head; // Record old head for check below
617620
setHead(node);
618621
/*
619-
* Try to signal next queued node if:
620-
* Propagation was indicated by caller,
621-
* or was recorded (as h.waitStatus either before
622-
* or after setHead) by a previous operation
623-
* (note: this uses sign-check of waitStatus because
624-
* PROPAGATE status may transition to SIGNAL.)
625-
* and
626-
* The next node is waiting in shared mode,
627-
* or we don't know, because it appears null
622+
* 如果发生以下情况,请尝试向下一个排队的节点发送信号:
623+
* 传播是由调用者指示的,
624+
* 或者是由上一个操作记录的(作为setHead之前或之后的h.waitStatus)
625+
* (请注意:这使用waitStatus的符号检查,因为PROPAGATE状态可能转换为SIGNAL。)
626+
* 以及
627+
* 下一个节点正在共享模式下等待,
628+
* 还是我们不知道,因为它看起来为null
628629
*
629-
* The conservatism in both of these checks may cause
630-
* unnecessary wake-ups, but only when there are multiple
631-
* racing acquires/releases, so most need signals now or soon
632-
* anyway.
630+
* 这两项检查中的保守性可能会导致不必要的唤醒,
631+
* 但仅当有多个争夺者获得释放时,因此无论现在还是不久,大多数人都需要发出信号。
633632
*/
634633
if (propagate > 0 || h == null || h.waitStatus < 0 ||
635634
(h = head) == null || h.waitStatus < 0) {
@@ -701,7 +700,8 @@ private void cancelAcquire(Node node) {
701700
*
702701
* 前者为signal,阻塞
703702
* 前者为cancel,更新前者
704-
* 其他情况:更新前者为signal
703+
* 其他情况:更新前者为signal(更新后再一轮尝试,还没有锁
704+
* 就会再次访问这里并阻塞了)
705705
*
706706
* @param pred node's predecessor holding status
707707
* @param node the node
@@ -722,6 +722,7 @@ private static boolean shouldParkAfterFailedAcquire(Node pred, Node node) {
722722
do {
723723
node.prev = pred = pred.prev;
724724
} while (pred.waitStatus > 0);
725+
//最后断掉这个废掉的链
725726
pred.next = node;
726727
} else {
727728
/*
@@ -1097,9 +1098,11 @@ protected boolean isHeldExclusively() {
10971098
* {@link #tryAcquire} but is otherwise uninterpreted and
10981099
* can represent anything you like.
10991100
*/
1101+
//先尝试获取锁,成功直接返回,失败则封装线程加入队列
11001102
public final void acquire(int arg) {
11011103
if (!tryAcquire(arg) &&
1102-
acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
1104+
//失败则封装线程加入队列
1105+
acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
11031106
selfInterrupt();
11041107
}
11051108

src/java/util/concurrent/locks/ReentrantLock.java

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,8 +125,11 @@ abstract static class Sync extends AbstractQueuedSynchronizer {
125125
final boolean tryLock() {
126126
Thread current = Thread.currentThread();
127127
int c = getState();
128+
//若c不为0,表示有人占用,若为自己占有,就走重入逻辑
128129
if (c == 0) {
130+
//尝试抢夺锁
129131
if (compareAndSetState(0, 1)) {
132+
//cas修改成功,就表示获得了锁,标记自己就行了
130133
setExclusiveOwnerThread(current);
131134
return true;
132135
}
@@ -172,15 +175,17 @@ final boolean tryLockNanos(long nanos) throws InterruptedException {
172175
@ReservedStackAccess
173176
protected final boolean tryRelease(int releases) {
174177
int c = getState() - releases;
178+
//只有拥有者才能进行释放
175179
if (getExclusiveOwnerThread() != Thread.currentThread())
176180
throw new IllegalMonitorStateException();
181+
//若free为0,表示锁解开,释放线程标记,释放信号量
177182
boolean free = (c == 0);
178183
if (free)
179184
setExclusiveOwnerThread(null);
180185
setState(c);
181186
return free;
182187
}
183-
188+
//直接判断是不是自己就行了
184189
protected final boolean isHeldExclusively() {
185190
// While we must in general read state before owner,
186191
// we don't need to do so to check if current thread is owner
@@ -262,6 +267,7 @@ final boolean initialTryLock() {
262267
Thread current = Thread.currentThread();
263268
int c = getState();
264269
if (c == 0) {
270+
//公平锁需要判断hasQueuedThreads()
265271
if (!hasQueuedThreads() && compareAndSetState(0, 1)) {
266272
setExclusiveOwnerThread(current);
267273
return true;
@@ -280,6 +286,12 @@ final boolean initialTryLock() {
280286
* Acquires only if thread is first waiter or empty
281287
*/
282288
protected final boolean tryAcquire(int acquires) {
289+
/**
290+
* 尝试进行抢夺锁,只有这几个条件满足时,才算成功,并且顺序很重要
291+
* 1. 信号量为0
292+
* 2. 前面没有排队的线程(公平锁才有的判断
293+
* 3. 尝试使用CAS抢夺并成功
294+
*/
283295
if (getState() == 0 && !hasQueuedPredecessors() &&
284296
compareAndSetState(0, acquires)) {
285297
setExclusiveOwnerThread(Thread.currentThread());

0 commit comments

Comments
 (0)