首頁  >  文章  >  Java  >  Java中synchronized鎖的升級過程是什麼?

Java中synchronized鎖的升級過程是什麼?

WBOY
WBOY轉載
2023-04-21 16:19:191742瀏覽

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鎖的升級過程是什麼?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:yisu.com。如有侵權,請聯絡admin@php.cn刪除