亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Java中synchronized鎖升級的方法是什么

發布時間:2023-04-14 11:45:58 來源:億速云 閱讀:112 作者:iii 欄目:開發技術

這篇“Java中synchronized鎖升級的方法是什么”文章的知識點大部分人都不太理解,所以小編給大家總結了以下內容,內容詳細,步驟清晰,具有一定的借鑒價值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來看看這篇“Java中synchronized鎖升級的方法是什么”文章吧。

synchronized鎖是啥?鎖其實就是一個對象,隨便哪一個都可以,Java中所有的對象都是鎖,換句話說,Java中所有對象都可以成為鎖。
這次我們主要聊的是synchronized鎖升級的套路

synchronized會經歷四個階段:無鎖狀態、偏向鎖、輕量級鎖、重量級鎖依次從耗費資源最少,性能最高,到耗費資源多,性能最差。

鎖原理

先看看這些狀態的鎖為什么稱之為鎖,他們的互斥原理是啥。

偏向鎖

當一個線程到達同步代碼塊,嘗試獲取鎖對象的時候,會查看對象頭中的MarkWord里的線程ID,如果這里沒有ID則將自己的保存進去,拿到鎖。若是有,則查看是否是當前線程,如果不是,就CAS嘗試改,如果是,就已經拿到了鎖資源。

這里詳細說說CAS嘗試修改的邏輯:它會檢查持有偏向鎖的線程狀態。首先遍歷當前JVM的所有存活的線程,如果能找到偏向的線程,則說明偏向的線程還存活,此時會檢查線程是否在執行同步代碼塊中的代碼,如果是,則升級為輕量級鎖,去繼續進行CAS競爭鎖。所以加了偏向鎖之后,同時只有一個線程可以拿到鎖執行同步代碼塊中的代碼。

輕量級鎖

查看對象頭中的MarkWord里的Lock Record指針指向的是否是當前線程的虛擬機棧,如果是,拿鎖執行業務,如果不是則進行CAS,嘗試修改,若是修改幾次都沒有成功,再升級到重量級鎖。

重量級鎖

查看對象頭中的MarkWord里的指向的ObjectMonitor,查看owner是否是當前線程,如果不是,扔到ObjectMonitor里的EntryList中排隊,并掛起線程,等待被喚醒。

鎖升級

無鎖

一般情況下,新new出來的一個對象,暫時就是無鎖狀態。因為偏向鎖默認是有延遲的,在啟動JVM的前4s中,不存在偏向鎖,但是如果關閉了偏向鎖延遲的設置,new出來的對象,就會添加一個匿名偏向鎖。也就是說這個對象想找一個線程去增加偏向鎖,但是沒有找到,稱之為匿名偏向。存儲的線程ID為一堆0000,也沒有任何地址信息。

我們可以通過以下配置關閉偏向鎖延遲。

//關閉偏向鎖延遲的指令
-XX:BiasedLockingStartuoDelay=0

偏向鎖

當某一個線程來獲取這個鎖資源時,此時會成功獲取到,就會變為偏向鎖,偏向鎖存儲線程的ID。

偏向鎖升級時,會觸發偏向鎖撤銷,偏向鎖撤銷需要等到一個安全點,比如GC的時候,偏向鎖撤銷的成本太高,所以默認開始時,會做偏向鎖延遲。若是直接有多個線程競爭,會跳過偏向鎖,直接變為輕量級鎖。

細說一下偏向鎖撤銷的過程,成本為啥高呢?當一個線程拿到偏向鎖之后,會把鎖的對象頭的Mark Work中的線程id指向自己,當又有一個線程來了進行爭搶導致鎖升級的的時候,會暫停之前拿到偏向鎖的線程,然后清空Mark Work中的線程id增加一個輕量級鎖,然后再恢復暫停的線程繼續執行。這也是為什么等到安全點再執行鎖升級的原因,因為要暫停線程。

常見的安全點:

  • 執行GC的時候

  • 方法返回之前

  • 調用某個方法之后

  • 拋出異常的位置

  • 一個循環的末尾

輕量級鎖

當在出現了多個線程的競爭,就會升級為輕量級鎖,輕量級鎖的效果就是基于CAS嘗試獲取鎖資源,這里會用到自適應自旋鎖,根據上次CAS成功與否,耗費的時間,決定這次自旋多少次。

輕量級鎖適用于競爭不是很激烈的場景,一個線程拿到鎖,執行同步代碼塊,很快就處理完了。再來一個線程嘗試一兩次也拿到了鎖,再去執行,不會讓一個線程等待很久。

重量級鎖

如果到了重量級鎖,那就沒啥說的了,如果有線程持有鎖,其他想拿鎖的就掛起,等待鎖釋放后被依次喚醒

鎖粗化&鎖消除

鎖粗化/鎖膨脹

鎖膨脹是編譯Java文件的時候,JIT幫我們做的優化,它會減少鎖的獲取和釋放次數。 比如:

while(){
   synchronized(){
      // 多次的獲取和釋放,成本太高,會被優化為下面這種
   }
}
synchronized(){
   while(){
       //  拿到鎖后執行循環,只加鎖和釋放一次
   }
}

鎖消除

鎖消除則是在一個加鎖的同步代碼塊中,沒有任何共享資源,也不存在鎖競爭的情況,JIT編譯時,就直接將鎖的指令優化掉。 比如

synchronized(){
   int a = 1;
   a++;
   //操作局部變量的邏輯
}

以上就是關于“Java中synchronized鎖升級的方法是什么”這篇文章的內容,相信大家都有了一定的了解,希望小編分享的內容對大家有幫助,若想了解更多相關的知識內容,請關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

隆尧县| 应用必备| 沁阳市| 拜城县| 霍州市| 大同市| 屏边| 公安县| 伊春市| 山阴县| 旬阳县| 卫辉市| 承德县| 布拖县| 伊宁市| 西平县| 建阳市| 荣昌县| 陇南市| 兴隆县| 新巴尔虎左旗| 镇安县| 丘北县| 潼关县| 沧源| 日土县| 甘泉县| 弥勒县| 渑池县| 衡东县| 板桥市| 黎平县| 兴山县| 涿鹿县| 长寿区| 集安市| 环江| 丹江口市| 白城市| 绥滨县| 东阿县|