java中ReentrantLock的公平鎖與非公平鎖
阿新 • • 發佈:2018-12-12
大家都知道ReentrantLock是基於jdk層面實現的可重入鎖,使用的時候有公平鎖與非公平鎖之分,預設採用非公平鎖。那麼公平鎖與非公平鎖的機制有何區別呢?非公平鎖的機制為什麼會提高效能呢?
在這裡不討論兩種鎖的具體實現,只講其思想。
1、首先兩者都維護一個執行緒等待佇列,所有沒獲取到鎖的執行緒都被掛起並進入這個佇列等待。
2、區別是:
公平鎖:執行緒按照佇列中的順序排隊獲取鎖。
非公平鎖:執行緒不一定要按照順序獲取鎖,可以插隊,那麼怎麼樣的情況下可以插隊呢?
下面用個例子說明:
假設一個房間(可以看成等待佇列)中有五個人(你們寢室是不是都五人一間)在睡覺(執行緒處於掛起狀態),現在,老師按照床號的順序叫醒每個人去搬東西,那每個人起床洗漱啥的起碼得磨蹭個十分鐘才能下樓(即喚醒執行緒),一號床的人幹完了,再叫二號床的人起床,這個機制可以看成公平鎖。
將要叫醒二號床的人幹活時,正好此時回來一個吃過早飯小明(即執行緒還沒有被掛起,還沒進入等待佇列),老師心想叫這人下樓幹活不需要刷牙洗臉浪費時間,可以直接拉到樓下(早起的蟲兒真可憐),這就節省了叫醒他時間。這就是非公平鎖的機制。(若當二號床的人正在起床時小明回來,那還是逃脫不了被直接拉去幹活的命運)。
因為可以搶佔鎖,所以線上程被喚醒的時間內就可能有執行緒拿到鎖,減少了執行緒掛起的機率,後來的執行緒有一定機率逃離被掛起的開銷,不用等待,直接幹活。這就是非公平鎖的優點。
當然,若沒有小明回來,那老師只能一個一個按順序叫醒了。