Semaphore 原始碼解析

2021-08-18 05:34:58 字數 2154 閱讀 1881

semaphore(訊號量), 從概念上講,訊號量維護一套許可。每次 acquire 方法呼叫都會根據需要進行阻塞,直到獲得許可為止,然後將其占用。每次 release 方法呼叫都會新增乙個許可,可能會喚醒因沒有獲取到許可而阻塞的執行緒。semaphore 基於 aqs 實現,不熟悉 aqs 的同學可以查閱筆者關於 aqs 原始碼分析的文章進行學習。關於 semaphore 的使用我們就不過多贅述了,直接進入原始碼分析,我們首先來看一下 semaphore 的構造方法:

semaphore:

public

semaphore

(int permits,

boolean fair)

permits 為許可的數量,fair 變數確定使用公平鎖或非公平鎖。semaphore 的另乙個過載的只有 permits 引數的構造方法使用的是非公平鎖。下面我們來看許可的獲取操作:

semaphore:

public

void

acquire()

throws interruptedexception

這裡的 acquiresharedinterruptibly 方法我們在 aqs(abstractqueuedsynchronizer)原始碼解析(共享鎖)這篇文章中已經詳細分析過 acquiresharedinterruptibly 方法,是可以響應中斷的共享鎖獲取方法,方法中會呼叫由子類實現的 tryacquireshared 方法實現共享鎖獲取邏輯,我們首先來看 semaphore 非公平鎖對於 tryacquireshared 方法的實現:

semaphore.nonfairsync:

protected

inttryacquireshared

(int acquires)

semaphore.sync:

final

intnonfairtryacquireshared

(int acquires)

}

這裡因為存在多執行緒競爭的情況,所以整個操作在自旋下完成。我們分析過 tryacquireshared 方法的返回值,這裡當剩餘許可數大於等於0時,代表獲取許可成功,小於0時代表獲取許可失敗,要進行阻塞等待。接下來我們來看 semaphore 公平鎖對於 tryacquireshared 方法的實現:

semaphore.fairsync:

protected

inttryacquireshared

(int acquires)

}

我們發現,公平鎖與非公平鎖對 tryacquireshared 方法的實現的唯一區別就是公平鎖首先會判斷是否存在應該先於當前執行緒獲得鎖的執行緒,如果存在說明當前執行緒不是下乙個應該獲取鎖的執行緒。hasqueuedpredecessors 方法主要確認以下幾種情況:

滿足上述三個條件的任意乙個,說明當前執行緒是下乙個可以獲取鎖的執行緒,反之則說明當前執行緒不是下乙個應該獲取鎖的執行緒,這時 tryacquireshared 方法會返回-1代表獲取共享鎖失敗。

下面我們來看釋放許可操作,釋放許可操作沒有公平和非公平之分:

semaphore:

public

void

release()

這裡的 releaseshared 釋放共享鎖方法同樣來自於 aqs,方法中首先會呼叫由子類覆蓋的 tryreleaseshared 方法,通過嘗試設定state變數來釋放共享鎖,我們來看 semaphore 對於 tryreleaseshared 方法的實現:

semaphore.sync:

protected

final

boolean

tryreleaseshared

(int releases)

}

整體來看,semaphore 就是基於 aqs 的共享鎖實現,如果理解了 aqs 的共享鎖,理解 semaphore 的實現原理還是比較簡單的。

Semaphore原始碼解析

public semaphore int permits public semaphore int permits,boolean fair permits 獲取許可的數量 fair 有公平和非公平 abstract static class sync extends abstractqueueds...

原始碼解析 Semaphore

建立 semaphore 例項的時候,需要乙個引數 permits,這個基本上可以確定是設定給 aqs 的 state 的,然後每個執行緒呼叫 acquire 的時候,執行 state state 1,release 的時候執行 state state 1,當然,acquire 的時候,如果 sta...

Semaphore訊號量原始碼解析

一 用法 訊號量,semaphore可以控同時訪問的執行緒個數,通過 acquire 獲取乙個許可,如果沒有就等待,而 release 釋放乙個許可。二 原始碼 構造方法,設定可以同時執行的執行緒數量。這裡可以設定是公平的,還是非公平的。這裡先說非公平的。acqurie 本質是aqs的方法,這個方法...