計數訊號量, 從概念上說,訊號量維持了一些許可。
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 的同學可以...