AQS臨界場景分析

2021-10-03 16:59:14 字數 3344 閱讀 2452

在實驗前,有幾點說明:

上面提過了,先unpark,在park。執行緒不會阻塞。不會出現無法喚醒的場景

這應該是比較普遍的情況。這樣前乙個執行緒釋放鎖後,後乙個執行緒就會被喚醒,然後往下執行(就是拿到鎖了

因為aqs中做了許多次判斷

那也有可能是在這一步判斷之後,前乙個執行緒才釋放鎖。那我們繼續跟著**往下走

final

boolean

acquirequeued

(final node node,

int arg)if(

shouldparkafte***iledacquire

(p, node)

&&//主要就是一步

parkandcheckinterrupt()

)//這一步就是park

interrupted =

true;}

}finally

}

我們進入shouldparkafte***iledacquire方法

第一次進來時pred的waitstatus肯定為0.因為前乙個執行緒對應node的status就是後面乙個執行緒設定的,該執行緒第一次進來。肯定還是預設值0.

private

static

boolean

shouldparkafte***iledacquire

(node pred, node node)

while

(pred.waitstatus >0)

; pred.next = node;

}else

return

false

;//因為是false。還會走外面的for迴圈

}

注意該場景的前提是前乙個執行緒此時已經unpark了。那麼該鎖就是空的狀態。而且欄位都是volatile的,所以當前執行緒可見再次判斷。下面條件肯定成立,當前執行緒不阻塞。相當於獲取到了鎖,繼續往下執行

if

(p == head &&

tryacquire

(arg)

){

執行緒a先執行到這一步

另乙個執行緒b開始繼續執行

說實話,如果真出現了這種場景。那麼確實第乙個執行緒會一直阻塞。現在我們需要分析。這種場景到底會不會出現

我們先分析執行緒b執行到這一步(return ture前面之前的幾種情況,

也就是這一步的情況

那說明b執行緒還沒走到下面這一步(這次宣告:微觀序列+可見性!!!是可以得出下面這個結論的)無法想到反例

那麼之後b執行緒必然會在下面一步退出,那麼執行緒a就不可能到park上面這一步。所以該情況不成立!

if

(p == head &&

tryacquire

(arg)

)

此時場景就回到了情況二(不是情況二,但很像!情況二是更後面的狀態,明確釋放了鎖.)(注意:釋放鎖,並不代表一定要upark。我這裡是指執行緒退出這個unlock方法),

waitstatus=0說明什麼?

說明執行緒a還沒有執行過下面這一步

但當b執行緒這一步時,b執行緒實際已經修改過state了

那麼執行緒a必然會在後面通過if條件實現獲取鎖,也就不會走到park那一步了

if

(p == head &&

tryacquire

(arg)

)

此時執行緒b會執行unpark(b執行緒)。那麼無論如何,b執行緒都不可能鎖死.繼續擴充套件一下那有沒有可能unpark了執行緒a,但a執行緒卻沒有park呢?可以確定的說:可以!因為我在本地通過debug模擬了這種情況,可以發生。

acquirequeued方法裡的for迴圈,多次判斷有點精髓。總感覺自己有點悟,但抓不到重點。

但還是記錄一下

trylock時為什麼先修改state?如果將tryrelease方法放後面執行,那麼肯定會出現一直阻塞的場景。可以想象一下情況4.1

如何保證執行緒阻塞了,那麼一定會在某個時刻被喚醒。其實就是上面幾種場景的分析。

就三句話

規定執行緒park前,需要將前乙個node的waitstatus設定為其他值(非零)如果明確有後任節點(waitstatus!=0時,這個後任節點就是第乙個排隊的節點,位置是第二個),那就不管三七二十一,unpark這個節點的執行緒(不管它是不是用的到

如果前乙個執行緒沒有執行unpark了(已成事實),為了保證不出現問題。只能在後任節點執行緒park前多做幾次檢查。因為沒有執行unpark(推斷出當時waitstatus=0),並且肯定已經設定state=0了,那麼後任節點只要在修改waitstatus前(也就是park前檢查state即可

AQS原始碼分析

如上 用jmeter模擬30個請求同時下單,結果30個請求都下單成功,產生了超賣問題。下面實現自定義乙個同步器來實現自定義鎖 2021 7 1 自定義aqs實現 public class mylock public void setstate int state public thread getl...

使用者分析,場景分析

典型使用者 1 1 李華 2 20歲 3 通過在學校經營零食屋有一點收入,不穩定。4 這種使用者比例較少。5 每次有別人想要買東西,都是在qq上詢問,假如在上課,也不清楚還有沒有這種東西,每次進貨也不清楚應該多進那種零食更好。6 進貨後在軟體進行登記,每次銷售後數量自動變化。隨時檢視存貨及銷售數量。...

AQS原始碼分析 08(LockSupport)

image.png object name image.png originheight 85 originwidth 599 size 5821 status done style none width 570 image.png object name image.png originheigh...