談談大廠愛問的Synchronized原理(建議收藏)
最近小夥伴大廠面試歸來,很多都被問到了Synchronized,很多同學對原理都忘了,下面我就再談談Synchronized的原理。
一般都會涉及到如下內容:內容底層實現,鎖升級、怎麼儲存等等,下面一一詳解@mikechen
Synchronized
synchronized關鍵字解決的是多個執行緒之間訪問資源的同步性,synchronized 翻譯為中文的意思是同步,也稱之為”同步鎖“。
synchronized的作用是保證在同一時刻, 被修飾的程式碼塊或方法只會有一個執行緒執行,以達到保證併發安全的效果。
Synchronized的使用方式
主要有3種使用方式:
1.修飾例項方法:作用於當前例項加鎖
2.修飾靜態方法:作用於當前類物件加鎖
3.修飾程式碼塊:指定加鎖物件,對給定物件加鎖
Synchronized的底層實現
synchronized的底層實現是完全依賴JVM虛擬機器的,所以談synchronized的底層實現,就不得不談資料在JVM記憶體的儲存:Java物件頭,以及Monitor物件監視器。
1.Java物件頭
在JVM虛擬機器中,物件在記憶體中的儲存佈局,可以分為三個區域:
物件頭(Header)
例項資料(Instance Data)
對齊填充(Padding)
Java物件頭主要包括兩部分資料:
1)型別指標(Klass Pointer)
是物件指向它的類後設資料的指標,虛擬機器透過這個指標來確定這個物件是哪個類的例項;
2)標記欄位(Mark Word)
用於儲存物件自身的執行時資料,如雜湊碼(HashCode)、GC分代年齡、鎖狀態標誌、執行緒持有的鎖、偏向執行緒 ID、偏向時間戳等等,它是實現輕量級鎖和偏向鎖的關鍵.
所以,很明顯synchronized使用的鎖物件是儲存在Java物件頭裡的標記欄位裡。
2.Monitor
monitor描述為物件監視器,可以類比為一個特殊的房間,這個房間中有一些被保護的資料,monitor保證每次只能有一個執行緒能進入這個房間進行訪問被保護的資料,進入房間即為持有monitor,退出房間即為釋放monitor。
上圖是syncrhoized同步程式碼塊反編譯截圖,可以很清楚的看見,主要就是透過鎖物件的monitor的取用(monitorenter)與釋放來(monitorexit)實現的。
3.執行緒狀態流轉在Monitor上體現
當多個執行緒同時請求某個物件監視器時,物件監視器會設定幾種狀態用來區分請求的執行緒:
Contention List:所有請求鎖的執行緒將被首先放置到該競爭佇列
Entry List:Contention List中那些有資格成為候選人的執行緒被移到Entry List
Wait Set:那些呼叫wait方法被阻塞的執行緒被放置到Wait Set
OnDeck:任何時刻最多隻能有一個執行緒正在競爭鎖,該執行緒稱為OnDeck
Owner:獲得鎖的執行緒稱為Owner
!Owner:釋放鎖的執行緒
下圖反映了個狀態轉換關係:
Synchronized 的鎖升級
鎖解決了資料的安全性,但是同樣帶來了效能的下降,hotspot 虛擬機器的作者經過調查發現,大部分情況下,加鎖的程式碼不僅僅不存在多執行緒競爭,而且總是由同一個執行緒多次獲得。
所以基於這樣一個機率,synchronized 在JDK1.6 之後做了一些最佳化,為了減少獲得鎖和釋放鎖來的效能開銷,引入了偏向鎖,鎖的狀態根據競爭激烈的程度從低到高不斷升級。
1.無鎖
無鎖沒有對資源進行鎖定,所有的執行緒都能訪問並修改同一個資源,但同時只有一個執行緒能修改成功。
2.偏向鎖
偏向鎖是JDK6中引入的一項鎖最佳化,大多數情況下,鎖不僅不存在多執行緒競爭,而且總是由同一執行緒多次獲得,為了讓執行緒獲得鎖的代價更低而引入了偏向鎖。
偏向鎖是指一段同步程式碼一直被一個執行緒所訪問,那麼該執行緒會自動獲取鎖,降低獲取鎖的代價。
3.輕量級鎖
是指當鎖是偏向鎖的時候,被另外的執行緒所訪問,偏向鎖就會升級為輕量級鎖,其他執行緒會透過自旋的形式嘗試獲取鎖,不會阻塞,從而提高效能。
4.重量級鎖
指的是原始的Synchronized的實現,重量級鎖的特點:其他執行緒試圖獲取鎖時,都會被阻塞,只有持有鎖的執行緒釋放鎖之後才會喚醒這些執行緒。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70024420/viewspace-2938830/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Web應用防火牆是什麼?談談原理及部署建議Web防火牆
- synchronized雜談synchronized
- 前端每日一問--談談instance的原理前端
- 從TCP協議的原理來談談RST復位攻擊TCP協議
- 談談構建有效資料治理策略的10條建議
- 談談stream的執行原理
- 【大廠面試06期】談一談你對Redis持久化的理解?面試Redis持久化
- 再談synchronized鎖升級synchronized
- 談一談全棧,為什麼不建議初學者去做全棧
- 談談三種工廠模式模式
- 解密國內BAT等大廠前端技術體系-阿里篇(長文建議收藏)解密BAT前端阿里
- 解密國內BAT等大廠前端技術體系-騰訊篇(長文建議收藏)解密BAT前端
- 談談Objective-C中的協議Object協議
- 【建議收藏】好用的API大全API
- 簡單談談DNS協議DNS協議
- 解密國內BAT等大廠前端技術體系-攜程篇(長文建議收藏)解密BAT前端
- 談談 Python 程式的執行原理Python
- 談談谷歌word2vec的原理谷歌
- Obie Fernandez談“我收到的最佳程式設計建議”NaN程式設計
- Rob Pike談“我收到的最佳程式設計建議”程式設計
- Erik Buck談“我收到的最佳程式設計建議”程式設計
- Danny Kalev談“我收到的最佳程式設計建議”程式設計
- Russ Olsen談“我收到的最佳程式設計建議”程式設計
- Bill Wagner談“我收到的最佳程式設計建議”程式設計
- 大廠紛紛入局女性向遊戲,換衣服談戀愛之外還能做什麼?遊戲
- 談談fork/join實現原理
- 談談分散式事務原理分散式
- 談談大資料採集和常見問題大資料
- 解密國內BAT等大廠前端技術體系-百度篇(長文建議收藏)解密BAT前端
- 【建議收藏】swoft的最佳實踐
- 淺談synchronized、Lock、ThreadLocal和semaphoresynchronizedthread
- 淺談WebSocket協議、WS協議和WSS協議原理及關係Web協議
- 談談 HTTP/2 的協議協商機制HTTP協議
- 從撤銷 rebase 談談 git 原理Git
- 阿里面試常問的redis資料結構,建議收藏阿里面試Redis資料結構
- 解密國內BAT等大廠前端技術體系-美團點評之下篇(長文建議收藏)解密BAT前端
- 歐美大廠談加班文化 一個遊戲業在所難免的問題遊戲
- 從原始碼角度談談AsyncTask的使用及其原理原始碼