在實驗前,有幾點說明:
上面提過了,先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...