簡單理解AQS ( 抽象的佇列同步器)

2021-10-06 19:21:55 字數 1767 閱讀 2879

abstractqueuedsynchronizer 類如其名,抽象的佇列式的同步器,aqs 定義了一套多執行緒訪問共享資源的同步器框架,許多同步類實現都依賴於它,如常用的 reentrantlock/semaphore/countdownlatch。

exclusive(獨佔,只有乙個執行緒能執行,如 reentrantlock)

share(共享,多個執行緒可同時執行,如 semaphore/countdownlatch)。

aqs 只是乙個框架,具體資源的獲取/釋放方式交由自定義同步器去實現, aqs 這裡只定義了乙個介面,具體資源的獲取交由自定義同步器去實現了(通過 state 的 get/set/cas)之所以沒有定義成abstract ,是 因 為獨 佔模 式 下 只 用實現 tryacquire-tryrelease ,而 共享 模 式 下 只用 實 現tryacquireshared-tryreleaseshared。如果都定義成abstract,那麼每個模式也要去實現另一模式下的介面。不同的自定義同步器爭用共享資源的方式也不同。自定義同步器在實現時只需要實現共享資源 state 的獲取與釋放方式即可,至於具體執行緒等待佇列的維護(如獲取資源失敗入隊/喚醒出隊等), aqs 已經在頂層實現好了。自定義同步器實現時主要實現以下幾種方法:

1. isheldexclusively():該執行緒是否正在獨佔資源。只有用到 condition 才需要去實現它。

2. tryacquire(int):獨佔方式。嘗試獲取資源,成功則返回 true,失敗則返回 false。

3. tryrelease(int):獨佔方式。嘗試釋放資源,成功則返回 true,失敗則返回 false。

4. tryacquireshared(int):共享方式。嘗試獲取資源。負數表示失敗; 0 表示成功,但沒有剩餘可用資源;正數表示成功,且有剩餘資源。

5. tryreleaseshared(int):共享方式。嘗試釋放資源,如果釋放後允許喚醒後續等待結點返回true,否則返回 false。

同步器的實現是 abs 核心(state 資源狀態計數)

同步器的實現是 abs 核心,以 reentrantlock 為例, state 初始化為 0,表示未鎖定狀態。 a 執行緒lock()時,會呼叫 tryacquire()獨佔該鎖並將 state+1。此後,其他執行緒再 tryacquire()時就會失敗,直到 a 執行緒 unlock()到 state=0(即釋放鎖)為止,其它執行緒才有機會獲取該鎖。當然,釋放鎖之前, a 執行緒自己是可以重複獲取此鎖的(state 會累加),這就是可重入的概念。但要注意,獲取多少次就要釋放多麼次,這樣才能保證 state 是能回到零態的。

以 countdownlatch 以例,任務分為 n 個子執行緒去執行, state 也初始化為 n(注意 n 要與執行緒個數一致)。這 n 個子執行緒是並行執行的, 每個子執行緒執行完後 countdown()一次, state會 cas 減 1。等到所有子執行緒都執行完後(即 state=0),會 unpark()主呼叫執行緒,然後主呼叫執行緒就會從 await()函式返回,繼續後余動作。

reentrantreadwritelock 實現獨佔和共享兩種方式一般來說,自定義同步器要麼是獨佔方法,要麼是共享方式,他們也只需實現 tryacquiretryrelease、 tryacquireshared-tryreleaseshared 中的一種即可。 但 aqs 也支援自定義同步器同時實現獨佔和共享兩種方式,如 reentrantreadwritelock。

抽象佇列同步器AQS

aqs具體實現及內部原理 aqs同步佇列具體實現結構 private volatile int state 共享變數,使用volatile修飾保證執行緒可見性share共享 多個執行緒可同時執行,如reentrantreadwritelock.readlock cyclicbarrier count...

old《1 3 1 AQS抽象佇列同步器詳解》

例1 以atomicinteger類的getandincrement 方法為例,它呼叫unsafe.getandaddint方法,而後者實際上就是cas 自旋。例2 private atomicreference owner newatomicreference void lock 底層也是使用的c...

同步器AQS中的同步佇列與等待佇列

在單純地使用鎖,比如reentrantlock的時候,這個鎖元件內部有乙個繼承同步器aqs的類,實現了其抽象方法,加鎖 釋放鎖也只是涉及到aqs中的同步佇列而已,那麼等待佇列又是什麼呢?當使用condition的時候,等待佇列的概念就出來了。condition的獲取一般都要與乙個鎖lock相關,乙個...