日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

Synchronized鎖優化

作者:WYSCODER 更新時間: 2022-05-11 編程語言

文章目錄

  • Synchronized鎖優化
    • (1)引言
    • (2)Java對象的內存布局
    • (3)偏向鎖
    • (4)輕量級鎖
    • (5)重量級鎖

Synchronized鎖優化

(1)引言

在JDK1.5之前,synchronized的底層實現都是重量級的,借助操作系統底層實現,也稱之為synchronized為重量級鎖,在JDK1.5之后,對Synchronized進行了各種優化,實現的原理是鎖升級的過程,有了偏向鎖輕量級鎖重量級鎖的概念。

(2)Java對象的內存布局

在這里插入圖片描述
在Java中,創建一個對象后,在JVM中,對象在內存中的存儲布局,分為三塊

  • 對象頭區域: 存放鎖信息、對象年齡等信息。
  • 實例數據區域: 存儲的是對象的真正有效的信息,比如對象中所有字段內容。
  • 對齊填充區域: JVM規定對象的起始地址必須是8字節的整數倍,如果一個對象實際占用的內存大小不是8字節的整數倍,就“補位”到8字節的整數倍,對齊填充區域的大小不是固定的。

synchronized用的鎖是存在對象頭里,如果對象是數組類型,對象頭中還包含了數組長度。

在這里插入圖片描述
如果是數組類型,則虛擬機使用3個字寬存儲對象頭,如果不是數組類型,則占用2個字寬存儲對象頭,在32位系統下,1字寬等于4字節即32bit位


在Java對象頭中Mark Word是默認存儲對象的hashcode分代年齡鎖的標記位。32位JVM中Mark Word默認存儲的結構如下圖所示:
在這里插入圖片描述


在Java SE1.6中,鎖一共存在4種狀態,級別從低到高依次是:無鎖狀態偏向鎖狀態輕量級鎖狀態重量級鎖狀態,這幾個狀態隨著競爭的情況逐漸升級,鎖是可以升級的但是不能降級,意味著偏向鎖升級成輕量級鎖再升級為重量級鎖,目的是為了提高獲取鎖和釋放鎖的效率。
在這里插入圖片描述

(3)偏向鎖

偏向鎖的操作是無需操作系統介入的,每個對象都有對象頭,對象頭中的Mark Word區域存儲對象的鎖信息。
在這里插入圖片描述
該對象頭先處于無鎖狀態,當有線程來訪問,JVM使用CAS操作將線程ID記錄到Mark Word中,修改偏向鎖的標識位,當前線程就擁有了這把鎖
在這里插入圖片描述
?注意:將線程ID通過CAS記錄,變更偏向鎖標識為1。

JVM不用和操作系統協商設置monitor,只需要記錄下線程ID,就表示當前線程擁有這把鎖,不用操作系統介入獲取鎖的線程就可以進入到程序代碼塊中執行,當線程再次執行時,JVM通過鎖對象的Mark Word判斷,如果當前線程ID還存在,就說明該線程還持有著這個對象的鎖,就直接進入臨界區執行,這個就是偏向鎖,在沒有別的線程競爭的時候,一直偏向當前的線程可以一直執行。

優點:只有一個線程執行同步塊時進一步提高性能,適用于一個線程反復獲取同一個鎖的情況,偏向鎖可以提高帶有同步但無競爭的程序的性能。

(4)輕量級鎖

如果在偏向鎖中一個線程A一直執行過程中,此時又來了另一個線程B要進入代碼塊中執行,但是鎖對象保存的是線程A的線程ID,還是偏向鎖,這時候就導致線程B無法執行,這個時候就需要對偏向鎖進行升級,變成一個輕量級鎖
JVM把鎖對象恢復成無鎖狀態,在當前的兩個線程的棧幀中各分配一個空間,叫做Lock Record,把鎖對象的Mark Word在兩個線程的棧幀中各復制一份,叫做Displaced Mark Word,將當前線程A的Lock Record的地址使用CAS放到鎖對象的Mark Word當中,并且將鎖的標識設置為00,意味著當前線程A獲取到輕量級鎖,可以進入到臨界區執行。
在這里插入圖片描述
線程B沒有獲取到鎖,但不阻塞,JVM會讓他自旋幾次,等待一會兒,當線程A退出了臨界區釋放鎖的時候,需要將Displaced Mark Word使用CAS復制回去,接下來線程B就可以通過CAS復制信息。這個時候兩個線程就可以交替進入臨界區,執行代碼。偏向鎖即使出現了競爭,想獲取鎖只要自旋幾次,等待一會,鎖就可以是釋放,使用CASLock Record就可以避免重量級鎖的開銷。


優點:絕大部分的鎖在整個生命周期中都存在少量競爭,在多線程交替執行同步代碼塊是可以避免重量級鎖引起的性能問題。

(5)重量級鎖

輕量級鎖在運行時,線程A正在持有鎖,另一個線程B自旋了好多次,線程A還沒有釋放鎖,這個時候JVM考慮自旋次數太多浪費CPU資源,就需要將鎖升級為重量級鎖,重量級鎖需要操作系統的介入,依賴操作系統底層的mutex lock,JVM會創建一個monitor對象,把這個對象的地址信息更新到Mark Word中,并將鎖標志置為10。
在這里插入圖片描述
線程A還在持有鎖運行,線程B直接掛起,線程進入阻塞,釋放掉占用的CPU資源。

原文鏈接:https://blog.csdn.net/sheng0113/article/details/124674155

欄目分類
最近更新