Java鎖升級過程


一、鎖種類

偏向鎖

因為經過HotSpot的作者大量的研究發現,大多數時候是不存在鎖競爭的,常常是一個線程多次獲得同一個鎖,因此如果每次都要競爭鎖會增大很多沒有必要付出的代價,為了降低獲取鎖的代價,才引入的偏向鎖。

輕量級鎖

輕量級鎖考慮的是競爭鎖對象的線程不多,而且線程持有鎖的時間也不長的情景。因為阻塞線程需要CPU從用戶態轉到內核態,代價較大,如果剛剛阻塞不久這個鎖就被釋放了,那這個代價就有點得不償失了,因此這個時候就干脆不阻塞這個線程,讓它自旋這等待鎖釋放。

自旋鎖

減少線程上下文切換,提高執行效率

重量級鎖

除擁有鎖的線程外阻塞所有競爭線程

二、具體過程

線程A在進入同步代碼塊前,先檢查MarkWord中的線程ID是否與當前線程ID一致,如果一致(還是線程A獲取鎖對象),則無需使用CAS來加鎖、解鎖。

如果不一致,再檢查是否為偏向鎖,如果不是,則自旋等待鎖釋放。

如果是,再檢查該線程是否存在(偏向鎖不會主動釋放鎖),如果不在,則設置線程ID為線程A的ID,此時依然是偏向鎖。

如果還在,則暫停該線程,同時將鎖標志位設置為00即輕量級鎖(將MarkWord復制到該線程的棧幀中並將MarkWord設置為棧幀中鎖記錄)。線程A自旋等待鎖釋放。

如果自旋次數到了該線程還沒有釋放鎖,或者該線程還在執行,線程A還在自旋等待,這時又有一個線程B過來競爭這個鎖對象,那么這個時候輕量級鎖就會膨脹為重量級鎖。重量級鎖把除了擁有鎖的線程都阻塞,防止CPU空轉。

如果該線程釋放鎖,則會喚醒所有阻塞線程,重新競爭鎖。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM