原始碼分析 Semaphore

2021-10-01 20:09:55 字數 2881 閱讀 1239

計數訊號量, 從概念上說,訊號量維持了一些許可。

public

class

semaphoretest).

start()

;}}protected

void

getinfo()

catch

(exception e)

finally

}}

他會2每秒列印10個值,沒10個執行緒 ,獲取許可,其他執行緒會被阻塞在semaphore.acquire(); 睡眠2秒後 semaphore.release(); 然後釋放許可,然後剩下的80個執行緒阻塞 ,10 個執行緒執行上面的邏輯!

乙個訊號量如果初始化值是1,就只有乙個許可,它在使用的時候就像是乙個排他鎖。只有乙個許可可用,或者許可不可用!

只接受乙個引數,建立乙個制定大小的訊號量以非公平的方式

public

semaphore

(int permits)

根據制定的方式建立

public

semaphore

(int permits,

boolean fair)

這個引數接受乙個是否是公平的方式的方式建立,當設定為flase,當前類不保證順序。

fairsync or nonfairsync 都繼承自 semaphore.sync 類,sync的建構函式如下:

sync

(int permits)

setstate()做了什麼事呢,它的實現是在abstractqueuedsynchronizer#setstate 方法 就是設定了aqs 的 state 屬性的值。

protected

final

void

setstate

(int newstate)

訊號量是用來控制資源訪問控制的話應該被設定為公平方式,為了保證執行緒不回 發生飢餓。獲取不到許可的情況。使用訊號量做其他的同步控制建議使用非公平的方式提高效能,避免入佇列。

acquire方法原始碼分析

public

final

void

acquiresharedinterruptibly

(int arg)

throws interruptedexception

上次分析aqs 是用的非公平這次來分析公平semaphore

protected

inttryacquireshared

(int acquires)

}

我們看這段邏輯

//小於零就是許可已經用完了if(

tryacquireshared

(arg)

<0)

//入佇列阻塞執行緒

doacquiresharedinterruptibly

(arg)

;

繼續doacquiresharedinterruptibly

private

void

doacquiresharedinterruptibly

(int arg)

throws interruptedexception

}//最後的嘗試如果沒有拿到 , 阻塞當前執行緒 這段** 執行可看lock 那篇文章if(

shouldparkafte***iledacquire

(p, node)

&&parkandcheckinterrupt()

)throw

newinterruptedexception()

;//迴圈上面的過程 }}

finally

}

上面就是大致的流程,那麼被阻塞的執行緒如何獲得執行的機會呢?

aqs 中release的實現是由releaseshared 方法。

public

final

boolean

releaseshared

(int arg)

return

false

;}

semaphore # tryreleaseshared

protected

final

boolean

tryreleaseshared

(int releases)

}

aqs中的doreleaseshared

原始碼中是這樣介紹當前方法的.

private

void

doreleaseshared()

else

if(ws ==0&&

!compareandsetwaitstatus

(h,0

, node.propagate)

)continue

;// loop on failed cas}if

(h == head)

// loop if head changed

break;}

}

locksupport.unpark 執行了當前方法的執行緒會繼續執行執行來了locksupport.park 的地方處喚醒。繼續執行。執行緒是阻塞在上面獲取鎖abstractqueuedsynchronizer#doacquiresharedinterruptibly那個for 迴圈會再次執行. 獲取到許可則執行返回。然後其他執行緒繼續等待傳播跟unpark 操作。

Semaphore原始碼分析

semaphore有兩種模式,公平模式和非公平模式。公平模式就是呼叫acquire的順序就是獲取許可證的順序,遵循fifo 而非公平模式是搶占式的,也就是有可能乙個新的獲取執行緒恰好在乙個許可證釋放時得到了這個許可證,而前面還有等待的執行緒。semaphore有兩個構造方法,如下 public se...

併發程式設計之 Semaphore 原始碼分析

併發 juc 包提供了很多任務具類,比如之前說的 countdownlatch,cyclicbarrier 今天說說這個 semaphore 訊號量,關於他的使用請檢視往期文章併發程式設計之 執行緒協作工具類,今天的任務就是從原始碼層面分析一下他的原理。如果先不看原始碼,根據以往我們看過的 coun...

Semaphore 原始碼解析

semaphore 訊號量 從概念上講,訊號量維護一套許可。每次 acquire 方法呼叫都會根據需要進行阻塞,直到獲得許可為止,然後將其占用。每次 release 方法呼叫都會新增乙個許可,可能會喚醒因沒有獲取到許可而阻塞的執行緒。semaphore 基於 aqs 實現,不熟悉 aqs 的同學可以...