面試官:小夥子知道synchronized的最佳化過程嗎?我:嘚吧嘚吧嘚,面試官:出去!

JavaBuild發表於2024-03-24

寫在開頭

面試官:小夥子,多執行緒中鎖用過嗎?
我:那是自然!
面試官:那你知道synchronized的最佳化嗎?
我:synchronized作為重鎖,開銷大,在早期不被推薦使用,後期進行了最佳化,至於怎麼最佳化的話,您讓我想想哈...
面試官:好的,那你出去好好想吧!

對於synchronized的最佳化,雖然被問到的場景不多,但在很多網友發的面經中發現很多人都會掛在這個點上。

在我們初學鎖時,很多人可能都覺得它是一個重量級鎖,程式碼中不建議使用,但其實現如今經過了層層最佳化後,synchronized被廣泛的應用在了JVM原始碼以及眾多開源框架中,我們今天就來一起學習一下synchronized的最佳化過程!

物件鎖的四種狀態

首先,我們這裡要記住一個Java迭代版本JDK1.6,這個版本對於synchronized來說是劃時代的,在此之前,synchronized確實是一種重量級悲觀鎖,這個時候的它使用起來極耗資源,為所有高效開發者所弊病,但在1.6版本之後,引入了“偏向鎖”和“輕量級鎖” 的概念,這極大減少了獲取synchronized鎖和釋放鎖所需資源,synchronized重獲新生!

在此之後,物件的鎖便擁有了4種狀態,根據鎖的級別從低到高可分為:

無鎖 -> 偏向鎖 -> 輕量級鎖 -> 重量級鎖

無鎖

無鎖其實很好理解,就是沒有對共享資源進行任何鎖定,所有執行緒都可以去訪問並修改同一資源,但同時只能有一個執行緒修改成功,其他執行緒不斷嘗試直至成功,並會將原內容覆蓋。

偏向鎖

偏向鎖,指的就是偏向第一個加鎖執行緒,物件的程式碼一直被同一執行緒執行,不存在多個執行緒競爭,該執行緒在後續的執行中自動獲取鎖,降低獲取鎖帶來的效能開銷。

輕量級鎖

輕量級鎖是指當鎖是偏向鎖的時候,被第二個執行緒 B 所訪問,此時偏向鎖就會升級為輕量級鎖,執行緒 B 會透過自旋的形式嘗試獲取鎖,執行緒不會阻塞,從而提高效能。

重量級鎖

指當有一個執行緒獲取鎖之後,其餘所有等待獲取該鎖的執行緒都會處於阻塞狀態。

重量級鎖透過物件內部的監視器(monitor)實現,而其中 monitor 的本質是依賴於底層作業系統的 Mutex Lock 實現,作業系統實現執行緒之間的切換需要從使用者態切換到核心態,切換成本非常高。所以在沒有被最佳化之前,synchronized這種重量級鎖,才不受重視!
image

物件鎖的儲存

學習完物件鎖的四種狀態後,我們繼續思考下一個問題,既然物件鎖有四種狀態,那它們是儲存在哪裡的呢?

會聯想的同學,我想已經猜出了大概,首先在Java中的鎖都是基於物件的,既然基於物件,那它存在的地方大機率要在物件中,而我們知道在JVM中,物件分為三個部分物件頭、例項資料、位元組對齊,其中物件頭又由Mark Word和Klass Point構成,而Mark Word(標記欄位)用於儲存物件自身的執行時資料,例如儲存物件的HashCode,分代年齡、鎖標誌位等資訊,是synchronized實現輕量級鎖和偏向鎖的關鍵。我們64位虛擬機器為例看下圖:
image

當物件狀態是偏向鎖時,MarkWord中儲存了偏向執行緒的ID,並且將是否偏向標誌置為1;當物件狀態是輕量級鎖時,Mark Word儲存的是指向執行緒棧中Lock Record的指標;當狀態為重量級鎖時,Mark Word為指向monitor(監視器)物件的指標。

synchronized 鎖升級的過程

有了上面的知識儲備,我們趁著打鐵,來聊一聊synchronized 鎖升級的過程,由低到高,逐漸升級。
1️⃣首先,在鎖物件的物件頭裡面有一個 threadid 欄位,未訪問時 threadid 為空,這時是無鎖狀態,任何執行緒都可競爭獲取共享資源;
2️⃣ 先得到共享資源的執行緒,其執行緒ID會被記錄到Mark Word中,此時鎖狀態為偏向鎖;
3️⃣ 當後續還有執行緒去獲取共享資源時,會先判斷 threadid 是否與其執行緒 id 一致。如果一致則可以直接使用此物件;如果不一致,則升級偏向鎖為輕量級鎖,透過自旋迴圈一定次數來獲取鎖;
4️⃣自旋的執行緒在自旋過程中,成功獲得資源(即之前獲的資源的執行緒執行完成並釋放了共享資源),則整個狀態依然處於 輕量級鎖的狀態,如果自旋失敗 。
5️⃣進入重量級鎖的狀態,這個時候,自旋的執行緒進行阻塞,等待之前執行緒執行完成並喚醒自己。

結尾彩蛋

如果本篇部落格對您有一定的幫助,大家記得留言+點贊+收藏呀。原創不易,轉載請聯絡Build哥!

image

如果您想與Build哥的關係更近一步,還可以關注“JavaBuild888”,在這裡除了看到《Java成長計劃》系列博文,還有提升工作效率的小筆記、讀書心得、大廠面經、人生感悟等等,歡迎您的加入!

image

相關文章