aqs學習

mic_saber發表於2019-04-26

aqs是一個很重要的併發框架,熟悉之後可以很方便的構造自己的併發工具。

aqs核心在於一個acquire方法。

public final void acquire(int arg) {
    if (!tryAcquire(arg) && acquireQueued(addWaiter(Node.EXCLUSIVE), arg)){
        selfInterrupt();
    }
}

1.tryAcquire(arg)
獲取鎖,獲取成功直接結束,
獲取失敗,進入2。
2.addWaiter(Node.EXCLUSIVE)
獲取失敗表示有人佔據了鎖,進入等待佇列,處理完成進入3。
3.acquireQueued(node,arg)
返回true會中斷,大部分情況會返回false。

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)) {
                setHead(node);
                p.next = null; // help GC
                failed = false;
                return interrupted; // 方法出口
            }
            if (shouldParkAfterFailedAcquire(p, node) && parkAndCheckInterrupt()){
                interrupted = true;
            }
        }
    } finally { //異常出口
        if (failed)
            cancelAcquire(node);
    }
}

finally邏輯先無視。

1.p == head
判斷成功走2,不成功走3。
2.tryAcquire(arg)
獲取成功返回,失敗走3。
3.shouldParkAfterFailedAcquire(p, node)
成功走4,不成功回到1。
4.parkAndCheckInterrupt()
成功修改狀態,失敗不修改,然後回到1。

相關文章