jvm synchronized底層設計與優化

2021-08-28 18:51:11 字數 1732 閱讀 4837

通常來講synchronized被當做重量級鎖來使用,但其實它並不是一味地阻塞當前執行緒,而是通過鎖公升級等方式進行了很多的優化。

最原始的,也是synchronized與生俱來的同步方式。

使用synchronized可以指定乙個鎖物件,如果沒有指定物件就是用當前物件的例項(非static的普通方法)或者當前物件的class物件(被static修飾的方法)作為被指定的鎖物件。鎖物件的鎖資訊放在鎖物件的頭資訊裡,由於考慮到提高虛擬機器空間使用效率等原因,這部分空間會根據不同的鎖狀態儲存不同的鎖資訊。如下圖所示。標誌位、儲存內容都在物件頭資訊中乙個叫markword的地方。

儲存內容

標誌位分代年齡、雜湊碼、偏向鎖開啟位

01(未鎖定)

輕量級鎖記錄指標

00(輕量級鎖定)

重量級鎖記錄指標

10(重量及鎖定)

無記錄11(gc)

偏向執行緒id、epoch、分代年齡、偏向鎖開啟位

01(可偏向)

執行synchronized**時,先嘗試獲取鎖物件的鎖,如果當前物件鎖的計數器是0(表示當前無線程競爭)或者計數器不為0單執行緒是同乙個執行緒(同乙個執行緒重入鎖),則當前執行緒獲取鎖,將鎖計數器加一;若釋放鎖則減一;若獲取物件失敗則當前執行緒阻塞等待,直到另乙個執行緒釋放。

jdk1.6之後加入的新型鎖機制,由於大多數時候是非併發狀態,此時重量級鎖消耗資源高且無用,因此加入了輕量級鎖。

加鎖過程如下:若尚未被鎖定(狀態為01)則在當前執行緒的棧頻中建立乙個lock record的鎖空間,用於copy鎖資訊,copy完成後,使用cas操作,將markword中的儲存內容換成指標(指標執行棧頻中lock record位置),再將markword的標誌位變為00。若cas操作失敗,則檢視是否markword中指標是否已經指向本執行緒的棧頻,若是,則執行緒已經持有此物件的鎖,若否,則執行緒被搶占,進入阻塞狀態。

解鎖過程如下:同樣使用cas操作,若指標依然指向本執行緒棧頻,則將lock record中的資訊複製到markword中。若cas失敗則存在其他併發執行緒,需釋放鎖的同時喚醒被阻塞的執行緒。

輕量級鎖適用於基本上不存在競爭的情況。一旦存在競爭不僅導致當前執行緒進入阻塞狀態,並且還有額外的cas開銷。

jdk1.6之後加入的新型鎖機制,如果說輕量級鎖防止了非併發情況下的阻塞操作,那麼偏向鎖就是去掉了單執行緒操作下cas操作。偏向鎖很適合初始化時,在迴圈中重複訪問的需加鎖的**。如建立concurrenthashmap後迴圈add操作。

所謂偏向鎖,就是加鎖**在第一次被執行緒訪問時在markword中記錄下執行緒id,如果以後還是這個執行緒在沒有併發的情況下訪問了,就可以進入**塊,如果有其他執行緒進入**塊,會觸發鎖公升級即,偏向鎖變為輕量級鎖。偏向鎖關閉後不會再進入。

下圖是偏向鎖、輕量級鎖、重量級鎖轉換模式。

jdk1.4.2之後引入的鎖機制,在輕量級鎖晉公升到重量級鎖時可以加入自旋鎖或者自適應鎖。

由於阻塞操作占用時間較長,有時甚至比同步**更加耗費資源,所以使用多次迴圈使用cas嘗試獲取鎖的方式,來減少併發狀況下阻塞的發生。如果成功獲取則跳出迴圈,進入普通輕量級鎖模式;如果失敗則繼續迴圈,直到次數用盡,阻塞當前執行緒。

自旋鎖迴圈次數預設是10次。但jdk1.6開始,迴圈鎖公升級為自適應鎖,迴圈次數由虛擬機器掌控。如果上次自旋獲取同步**的鎖的時間較短,這次自旋時間就會延長,因為虛擬機器認為這段**執行很快,使用自旋很容易獲取到鎖;相反,就會縮短自旋時間,甚至會取消自旋,以節省消耗。

MFC底層設計

include lresult callback windowproc hwnd hwnd,訊息控制代碼 uint umsg,具體訊息 wparam wparam,鍵盤附加訊息 lparam lparam 滑鼠附加訊息 case wm keydown messagebox hwnd,text key...

Redis的字典結構底層設計

相比前兩種sds和list結構而言,字典的結構相對來說要複雜,主要涉及的都是和雜湊相關的問題,包括但不限於雜湊衝突的解決。雜湊的擴容策略,雜湊演算法等。其主要用在redis的底層資料庫底層實現,雜湊鍵的底層實現。ht屬性是乙個包含兩個項的陣列,陣列中的每個項都是乙個dictht雜湊表,一般情況下,字...

底層通訊協議的設計

對於很多裝置之間的通訊,經常需要自己設計一套通訊協議。當然此處的通訊協議一般都是建立在tcpip協議等協議基礎之上的協議,也就是在已有協議的基礎之上,在定義一套協議。例如 有一套檢測降雨量的裝置 一般為簡單的嵌入式裝置 需要把採集到的的資料上報給中心伺服器 一般為一台效能特別好的計算機 就需要一套通...