您好,登錄后才能下訂單哦!
這篇“Java synchronized輕量級鎖如何實現”文章的知識點大部分人都不太理解,所以小編給大家總結了以下內容,內容詳細,步驟清晰,具有一定的借鑒價值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來看看這篇“Java synchronized輕量級鎖如何實現”文章吧。
輕量級鎖是JDK 6之中加入的新型鎖機制,它名字中的“輕量級”是相對于使用monitor的傳統鎖而言的。輕量級鎖指的是存在多線程競爭,但是任意時刻最多只允許一個線程競爭獲得鎖,即不存在鎖競爭太過激烈的情況,輕量級鎖情況下,線程不會發生阻塞。
輕量級鎖考慮的是競爭鎖對象的線程不多,而且線程持有鎖的時間也不長的場景。因為阻塞線程需要CPU從用戶態轉到內核態,代價比較大,如果剛剛阻塞不久這個鎖就被釋放了,那這個代價就有點得不償失了,因此這個時候就干脆不阻塞這個線程,讓它自旋這等待鎖的釋放。
主要有兩個:
1)、關閉偏向鎖功能
使用 -XX:-UseBiasedLocking參數關閉偏向鎖,此時默認進入輕量級鎖;
2)、多個線程競爭偏向鎖
偏向鎖狀態下,由于別的線程嘗試競爭偏向鎖,并且CAS更新MarkWord中線程ID失敗,此時發生【偏向鎖 -> 輕量級鎖】升級;
舉個例子:
1、線程A先獲取到鎖對象,線程B又過來嘗試競爭這個鎖,此時該鎖已是偏向鎖偏向線程A了;
2、線程B嘗試執行CAS去替換鎖對象MarkWord中線程ID,看下能不能獲取到鎖;
3、如果線程B的CAS成功了,說明此時線程A執行完了同步塊代碼,這個時候線程B會直接替換鎖對象MarkWord中線程ID為自己的線程ID,該鎖不會發生升級,還是處于偏向鎖狀態;
4、如果線程B的CAS失敗了,說明線程A還沒執行完同步塊代碼,這個時候,偏向鎖就會升級為輕量級鎖(偏向鎖標識置為0,同步鎖標識置為00),這個輕量級鎖由原來持有偏向鎖的線程A持有,繼續執行同步代碼,此時正在競爭的線程B會進入CAS自旋等待獲取這個輕量級鎖;
前面我們了解到,當關閉偏向鎖功能的時候,默認獲取的是輕量級鎖。所以我們這里添加運行時參數 -XX:-UseBiasedLocking參數禁用偏向鎖。
public class LightweightLockDemo01 { public static void main(String[] args) { // 關閉偏向鎖,默認進入輕量級鎖 Object objLock = new Object(); new Thread(() -> { synchronized (objLock) { System.out.println(ClassLayout.parseInstance(objLock).toPrintable()); } }, "t1").start(); } }
可以看到,對象頭最后三位為“000”,表示當前獲取的是一把輕量級鎖。
輕量級鎖的加鎖
1)、JVM會在當前線程的棧幀中建立一個名為鎖記錄(Lock Record)的空間,用于存儲鎖對象目前的Mark Word的拷貝(官方稱為Displaced Mark Word)。若一個線程獲得鎖時發現是輕量級鎖,它會將對象的Mark Word復制到棧幀中的鎖記錄Lock Record中(Displaced Mark Word里面);
2)、線程嘗試利用CAS操作將對象的Mark Word更新為指向Lock Record的指針,如果成功表示當前線程競爭到鎖,則將鎖標志位變成00,執行同步操作;
3)、如果失敗,表示MarkWord已經被替換成了其他線程的鎖記錄,說明在與其他線程搶占競爭鎖,當前線程就嘗試使用自旋來獲取鎖;
注意,JVM采用的是自適應自旋,也就是說,自適應意味著自旋的次數不是固定不變的,JVM會根據同一個鎖上一次自旋的時間以及擁有鎖線程的狀態來決定到底需要自旋多少次。JVM針對那些很少會自旋成功的線程,那么下次會減少自旋的次數甚至壓根不自旋,避免CPU空轉。
輕量級鎖的釋放
輕量級鎖的釋放也是通過CAS操作來進行的,當前線程使用CAS操作將Displaced Mark Word的內存復制回鎖對象的MarkWord中,如果CAS操作替換成功,則說明釋放鎖成功;如果CAS自旋多次還是替換失敗的話,說明有其他線程嘗試獲取該鎖,則需要將輕量級鎖膨脹升級為重量級鎖;
優點
在多線程交替執行同步塊的情況下,可以避免重量級鎖引起的性能消耗;
缺點
如果長時間自旋后還沒競爭到鎖,將會過度耗費CPU,即CPU空轉。
以上就是關于“Java synchronized輕量級鎖如何實現”這篇文章的內容,相信大家都有了一定的了解,希望小編分享的內容對大家有幫助,若想了解更多相關的知識內容,請關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。