juc併發工具二-AQS

目錄

 

1 AQS概述

2 模板方法模式

2.1 獨佔方式獲取資源

2.2 獨佔方式釋放資源

2.3 共享方式獲取資源

2.4 共享方式釋放資源


1 AQS概述

AQS全稱即AbstractQueuedSynchronizer,抽象隊列同步器,提供了一套依賴隊列實現的FIFO的同步器框架,ReentrantLock,Semaphore,CyclicBarrier,CountDownLatch都是基於AQS實現的
AQS內部維護了一個volatile的state變量和一個CLH隊列,框架圖如下
AQS隊列模型

2 模板方法模式

AQS定義了一組模版方法供子類覆蓋
tryAcquire(int):獨佔方式。嘗試獲取資源,成功則返回true,失敗則返回false。
tryRelease(int):獨佔方式。嘗試釋放資源,成功則返回true,失敗則返回false。
tryAcquireShared(int):共享方式。嘗試獲取資源。負數表示失敗;0表示成功,但沒有剩餘可用資源;正數表示成功,且有剩餘資源。
tryReleaseShared(int):共享方式。嘗試釋放資源,如果釋放後允許喚醒後續等待結點返回true,否則返回false。
isHeldExclusively():該線程是否正在獨佔資源。只有用到condition才需要去實現它。

2.1 獨佔方式獲取資源

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


首先嚐試獲取資源,如果獲取資源失敗則將當前線程以獨佔的方式添加到執行隊列尾部
acquireQueued方法基於CAS不斷嘗試獲取資源,有興趣的同學可以看看源碼實現機制

2.2 獨佔方式釋放資源

    public final boolean release(int arg) {
        if (tryRelease(arg)) {
            Node h = head;
            if (h != null && h.waitStatus != 0)
                unparkSuccessor(h);
            return true;
        }
        return false;
    }

如果釋放資源成功並且隊列中有正在等待的線程則通過unparkSuccessor方法喚醒其中一個waitStatus<0的線程
waitStatus有如下幾個狀態:

    // 表徵等待線程已取消的
    static final int CANCELLED =  1;
    // 表徵需要喚醒後續線程
    static final int SIGNAL    = -1;
    // 表徵線程正在等待觸發條件(condition)
    static final int CONDITION = -2;
    // 表徵下一個acquireShared應無條件傳播
    static final int PROPAGATE = -3;

2.3 共享方式獲取資源

    public final void acquireShared(int arg) {
        if (tryAcquireShared(arg) < 0)
            doAcquireShared(arg);
    }

    如果獲取成功則直接返回。如果獲取失敗則進入等待隊列,自旋的方式不斷嘗試獲取資源
    tryAcquireShared方法返回結果說明:
        >0:獲取資源成功,並且還有剩餘資源
        =0:獲取資源成功,但是已經沒有剩餘資源
        <=:獲取資源失敗

2.4 共享方式釋放資源

    public final boolean releaseShared(int arg) {
        if (tryReleaseShared(arg)) {
            doReleaseShared();
            return true;
        }
        return false;
    }

 如果嘗試釋放資源成功,則進行釋放資源並且喚醒下一個線程,返回true,否則返回false
部分內容參考文章:https://www.jianshu.com/p/0f876ead2846

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章