AQS共享鎖應用之Semaphore原理

2021-09-07 18:40:48 字數 2965 閱讀 2617

我們呼叫semaphore方法時,其實是在間接呼叫其內部類或aqs方法執行的。semaphore類結構與reetrantlock類相似,內部類sync繼承自aqs,然後其子類fairsync和nofairsync分別實現公平鎖和非公平鎖的獲取鎖方法tryacquireshared(int arg),而釋放鎖的tryreleaseshared(int arg)方法則有sync類實現,因為非公平或公平鎖的釋放過程都是相同的。

aqs通過state值來控制對共享資源訪問的執行緒數,有執行緒請求同步狀態成功state值減1,若超過共享資源數量獲取同步狀態失敗,則將執行緒封裝共享模式的node結點加入到同步佇列等待。有執行緒執行完任務釋放同步狀態後,state值會增加1,同步佇列中的執行緒才有機會獲得執行權。公平鎖與非公平鎖不同在於公平鎖申請獲取同步狀態前都會先判斷同步佇列中釋放存在node,若有則將當前執行緒封裝成node結點入隊,從而保證按fifo的方式獲取同步狀態,而非公平鎖則可以直接通過競爭獲取執行緒執行權。

//

semaphore的acquire()

public

void acquire() throws

interruptedexception

/*** 注意sync類繼承自aqs

* aqs的acquiresharedinterruptibly()方法

*/public

final

void acquiresharedinterruptibly(int

arg)

throws

interruptedexception

//semaphore中非公平鎖nonfairsync的tryacquireshared()

protected

int tryacquireshared(int

acquires)

final

int nonfairtryacquireshared(int

acquires)

}private

void doacquiresharedinterruptibly(int

arg)

throws

interruptedexception

}//調整同步佇列中node結點的狀態並判斷是否應該被掛起

//並判斷是否需要被中斷,如果中斷直接丟擲異常,當前結點請求也就結束

if (shouldparkafte***iledacquire(p, node) &&parkandcheckinterrupt())

throw

newinterruptedexception();}}

finally

}private

static

boolean

shouldparkafte***iledacquire(node pred, node node)

while (pred.waitstatus > 0);

pred.next =node;

} else

return

false

; }

private

final

boolean

parkandcheckinterrupt()

//不可中的acquireshared()

public

final

void acquireshared(int

arg)

private

void doacquireshared(int

arg)

}if (shouldparkafte***iledacquire(p, node) &&parkandcheckinterrupt())

//沒有丟擲異常中的。。。。

interrupted = true

; }

} finally

}private

void setheadandpropagate(node node, int

propagate)

}//semaphore的release()

public

void

release()

//呼叫到aqs中的releaseshared(int arg)

public

final

boolean releaseshared(int

arg)

return

false

; }

//在semaphore的內部類sync中實現的

protected

final

boolean tryreleaseshared(int

releases)

}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

; }}//

喚醒傳入結點的後繼結點對應的執行緒

private

void

unparksuccessor(node node)

if (s != null

)

//喚醒該執行緒

locksupport.unpark(s.thread);

}

剖析基於併發aqs的共享鎖的實現(基於訊號量semaphore)

AQS(三) 共享鎖

共享式獲取同步狀態,與獨佔式的區別在於同一時刻有多個執行緒獲取同步狀態 共享式獲取同步狀態,與獨佔式的區別在於同一時刻有多個執行緒獲取同步狀態 void acquireshared int arg 在acquireshared方法基礎上增加了能響應中斷的功能 void acquiresharedin...

AQS共享鎖的實現原理

前面的文章lock的實現中分析了aqs獨佔鎖的實現原理,那麼接下來就分析下aqs是如何實現共享鎖的。共享鎖的介紹 共享鎖 同一時刻有多個執行緒能夠獲取到同步狀態。那麼它是如何做到讓多個執行緒獲取到同步狀態呢?來看一下獲取共享鎖的過程 1.執行緒呼叫aqs的acquireshared 申請獲取鎖 可有...

深入淺出AQS之共享鎖模式

在了解了aqs獨佔鎖模式以後,接下來再來看看共享鎖的實現原理。搞清楚aqs獨佔鎖的實現原理之後,再看共享鎖的實現原理就會輕鬆很多。兩種鎖模式之間很多通用的地方本文只會簡單說明一下,就不在贅述了,具體細節可以參考我的上篇文章深入淺出aqs之獨佔鎖模式 一 執行過程概述 獲取鎖的過程 當執行緒呼叫acq...