鎖優(yōu)化

1. 自旋鎖與自適應(yīng)自旋

  • 為了讓線程等待,我們只須讓線程執(zhí)行一個忙循環(huán)(自旋)。自旋等待不能代替阻塞,如果鎖被占用的時間很短,自旋等待的效果就會非常好,反之如果鎖被占用的時間很長這就會帶來性能的浪費。因此自旋等待的時間必須有一定的限度,如果自旋超過了限定的次數(shù)仍然沒有成功獲得鎖,就應(yīng)當使用傳統(tǒng)的方式去掛起線程。
  • 自適應(yīng)意味著自旋的時間不再是固定的了,而是由前一次在同一個鎖上的自旋時間及鎖的擁有者的狀態(tài)來決定的。

2. 鎖消除

鎖消除是指對一些代碼要求同步,但是對被檢測到不可能存在共享數(shù)據(jù)競爭的鎖進行消除。判定依據(jù)來源于逃逸分析。如果判斷到一段代碼中,在堆上的所有數(shù)據(jù)都不會逃逸出去被其他線程訪問到,那就可以把它們當作棧上數(shù)據(jù)對待,認為它們是線程私有的,同步加鎖自然就無須再進行。

3. 鎖粗化

如果有一串零碎的操作都對同一個對象加鎖,將會把加鎖同步的范圍擴展(粗化)到整個操作序列的外部。

4. 輕量級鎖

代碼即將進入同步塊的時候,如果此同步對象沒有被鎖定(鎖標志位為“01”狀態(tài)),在當前線程的棧幀中建立一個名為鎖記錄(Lock Record)的空間,用于存儲鎖對象目前的Mark Word的拷貝,然后將使用CAS操作嘗試把對象的Mark Word更新為指向Lock Record的指針。
如果這個更新動作成功了,即代表該線程擁有了這個對象的鎖,并且對象Mark Word的鎖標志位將轉(zhuǎn)變?yōu)椤?0”,表示此對象處于輕量級鎖定狀態(tài)。
如果這個更新操作失敗了,那就意味著至少存在一條線程與當前線程競爭獲取該對象的鎖。虛擬機首先會檢查對象的Mark Word是否指向當前線程的棧幀,如果是,說明當前線程已經(jīng)擁有了這個對象的鎖,那直接進入同步塊繼續(xù)執(zhí)行就可以了,否則就說明這個鎖對象已經(jīng)被其他線程搶占了。如果出現(xiàn)兩條以上的線程爭用同一個鎖的情況,那輕量級鎖就不再有效,必須要膨脹為重量級鎖,鎖標志的狀態(tài)值變?yōu)椤?0”,此時Mark Word中存儲的就是指向重量級鎖(互斥量)的指針,后面等待鎖的線程也必須進入阻塞狀態(tài)。

5. 偏向鎖

消除數(shù)據(jù)在無競爭情況下的同步原語。這個鎖會偏向于第一個獲得它的線程,如果在接下來的執(zhí)行過程中,該鎖一直沒有被其他的線程獲取,則持有偏向鎖的線程將永遠不需要再進行同步。

當鎖對象第一次被線程獲取的時候,虛擬機將會把對象頭中的標志位設(shè)置為“01”、把偏向模式設(shè)置為“1”,表示進入偏向模式。同時使用CAS操作把獲取到這個鎖的線程的ID記錄在對象的Mark Word之中。如果CAS操作成功,持有偏向鎖的線程以后每次進入這個鎖相關(guān)的同步塊時,虛擬機都可以不再進行任何同步操作。
一旦出現(xiàn)另外一個線程去嘗試獲取這個鎖的情況,偏向模式就馬上宣告結(jié)束。根據(jù)鎖對象目前是否處于被鎖定的狀態(tài)決定是否撤銷偏向(偏向模式設(shè)置為“0”),撤銷后標志位恢復到未鎖定(標志位為“01”)或輕量級鎖定(標志位為“00”)的狀態(tài),后續(xù)的同步操作就按照上面介紹的輕量級鎖那樣去執(zhí)行。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容