Java培訓(xùn)教程:Java多線程詳解之Synchronized的底層實(shí)現(xiàn)

Java培訓(xùn)教程:Java多線程詳解之Synchronized的底層實(shí)現(xiàn)

長(zhǎng)沙一度軟件培訓(xùn)      2022-05-07 00:28:01     75

Java培訓(xùn)教程:Java多線程詳解之Synchronized的底層實(shí)現(xiàn),  Java面試的時(shí)候經(jīng)常會(huì)被問到Java多線程相關(guān)的問題,尤其喜歡問:  synchronized的底層實(shí)現(xiàn)原理  synchronized鎖與JVM的

課程價(jià)格 請(qǐng)咨詢

上課時(shí)段: 授課校區(qū):

詳細(xì)介紹


  Java面試的時(shí)候經(jīng)常會(huì)被問到Java多線程相關(guān)的問題,尤其喜歡問:


  synchronized的底層實(shí)現(xiàn)原理


  synchronized鎖與JVM的關(guān)系


  synchronized的鎖升級(jí)順序


  synchronized的鎖優(yōu)劣勢(shì)與應(yīng)用場(chǎng)景


  今天主要分享以上內(nèi)容,詳解synchronized的底層實(shí)現(xiàn)。


  Synchronized(同步鎖)


  synchronized 翻譯為中文的意思是同步,也稱之為”同步鎖“。


  synchronized的作用是保證在同一時(shí)刻, 被修飾的代碼塊或方法只會(huì)有一個(gè)線程執(zhí)行,以達(dá)到保證并發(fā)安全的效果。


  Synchronized的使用


  1.synchronized的3種使用方式


  修飾實(shí)例方法:作用于當(dāng)前實(shí)例加鎖


  修飾靜態(tài)方法:作用于當(dāng)前類對(duì)象加鎖


  修飾代碼塊:指定加鎖對(duì)象,對(duì)給定對(duì)象加鎖


  2.synchronized的代碼范例



  Synchronized的底層實(shí)現(xiàn)


  synchronized的底層實(shí)現(xiàn)是完全依賴與JVM虛擬機(jī)的。


  所以談synchronized的底層實(shí)現(xiàn),就不得不談數(shù)據(jù)在JVM內(nèi)存的存儲(chǔ):Java對(duì)象頭,以及Monitor對(duì)象監(jiān)視器。


  1.Java對(duì)象頭


  在JVM虛擬機(jī)中,對(duì)象在內(nèi)存中的存儲(chǔ)布局,可以分為三個(gè)區(qū)域:


  對(duì)象頭(Header)


  實(shí)例數(shù)據(jù)(Instance Data)


  對(duì)齊填充(Padding)


  Java對(duì)象頭主要包括兩部分?jǐn)?shù)據(jù):


  類型指針(Mark Word):是對(duì)象指向它的類元數(shù)據(jù)的指針,虛擬機(jī)通過這個(gè)指針來確定這個(gè)對(duì)象是哪個(gè)類的實(shí)例;


  標(biāo)記字段(Klass Pointer):用于存儲(chǔ)對(duì)象自身的運(yùn)行時(shí)數(shù)據(jù),如哈希碼(HashCode)、GC分代年齡、鎖狀態(tài)標(biāo)志、線程持有的鎖、偏向線程 ID、偏向時(shí)間戳等等,它是實(shí)現(xiàn)輕量級(jí)鎖和偏向鎖的關(guān)鍵.


  2.Java鎖對(duì)象存儲(chǔ)位置


  所以,很明顯synchronized使用的鎖對(duì)象是存儲(chǔ)在Java對(duì)象頭里的標(biāo)記字段里。


  3.Monitor


  synchronized的對(duì)象鎖,其指針指向的是一個(gè)monitor對(duì)象(由C++實(shí)現(xiàn))的起始地址。每個(gè)對(duì)象實(shí)例都會(huì)有一個(gè) monitor。


  Monitor描述為對(duì)象監(jiān)視器,可以類比為一個(gè)特殊的房間,這個(gè)房間中有一些被保護(hù)的數(shù)據(jù),Monitor保證每次只能有一個(gè)線程能進(jìn)入這個(gè)房間進(jìn)行訪問被保護(hù)的數(shù)據(jù),進(jìn)入房間即為持有Monitor,退出房間即為釋放Monitor。


  使用syncrhoized加鎖的同步代碼塊在字節(jié)碼引擎中執(zhí)行時(shí),主要就是通過鎖對(duì)象的monitor的取用與釋放來實(shí)現(xiàn)的。


  4.線程狀態(tài)流轉(zhuǎn)


  當(dāng)多個(gè)線程同時(shí)請(qǐng)求某個(gè)monitor時(shí),monitor會(huì)設(shè)置幾種狀態(tài)用來區(qū)分請(qǐng)求的線程:


  Contention List:所有請(qǐng)求鎖的線程將被首先放置到該競(jìng)爭(zhēng)隊(duì)列


  Entry List:Contention List中那些有資格成為候選人的線程被移到Entry List


  Wait Set:那些調(diào)用wait方法被阻塞的線程被放置到Wait Set


  OnDeck:任何時(shí)刻最多只能有一個(gè)線程正在競(jìng)爭(zhēng)鎖,該線程稱為OnDeck


  Owner:獲得鎖的線程稱為Owner


  !Owner:釋放鎖的線程


  下圖反映了個(gè)狀態(tài)轉(zhuǎn)換關(guān)系



  Synchronized 鎖的升級(jí)


  鎖解決了數(shù)據(jù)的安全性,但是同樣帶來了性能的下降。hotspot 虛擬機(jī)的作者經(jīng)過調(diào)查發(fā)現(xiàn),大部分情況下,加鎖的代碼不僅僅不存在多線程競(jìng)爭(zhēng),而且總是由同一個(gè)線程多次獲得。所以基于這樣一個(gè)概率。


  synchronized 在JDK1.6 之后做了一些優(yōu)化,為了減少獲得鎖和釋放鎖來的性能開銷,引入了偏向鎖、輕量級(jí)鎖、自旋鎖、重量級(jí)鎖,鎖的狀態(tài)根據(jù)競(jìng)爭(zhēng)激烈的程度從低到高不斷升級(jí)。


  1.偏向鎖


  偏向鎖是JDK6中引入的一項(xiàng)鎖優(yōu)化,大多數(shù)情況下,鎖不僅不存在多線程競(jìng)爭(zhēng),而且總是由同一線程多次獲得,為了讓線程獲得鎖的代價(jià)更低而引入了偏向鎖。


  偏向鎖會(huì)偏向于第一個(gè)獲得它的線程,如果在接下來的執(zhí)行過程中,該鎖沒有被其他的線程獲取,則持有偏向鎖的線程將永遠(yuǎn)不需要同步。


  2.輕量級(jí)鎖


  如果明顯存在其它線程申請(qǐng)鎖,那么偏向鎖將很快升級(jí)為輕量級(jí)鎖。


  3.自旋鎖


  自旋鎖原理非常簡(jiǎn)單,如果持有鎖的線程能在很短時(shí)間內(nèi)釋放鎖資源,那么那些等待競(jìng)爭(zhēng)鎖的線程就不需要做內(nèi)核態(tài)和用戶態(tài)之間的切換進(jìn)入阻塞掛起狀態(tài),它們只需要等一等(自旋),等持有鎖的線程釋放鎖后即可立即獲取鎖,這樣就避免用戶線程和內(nèi)核的切換的消耗。


  4.重量級(jí)鎖


  指的是原始的Synchronized的實(shí)現(xiàn),重量級(jí)鎖的特點(diǎn):其他線程試圖獲取鎖時(shí),都會(huì)被阻塞,只有持有鎖的線程釋放鎖之后才會(huì)喚醒這些線程。



       以上就是長(zhǎng)沙一度軟件培訓(xùn)Java培訓(xùn)機(jī)構(gòu)小編介紹的“Java培訓(xùn)教程:Java多線程詳解之Synchronized的底層實(shí)現(xiàn)”的內(nèi)容,希望對(duì)大家有幫助,如有疑問,請(qǐng)?jiān)诰€咨詢,有專業(yè)老師隨時(shí)為你服務(wù)。


  相關(guān)內(nèi)容


  Java多線程編程詳解


  java多線程的狀態(tài)轉(zhuǎn)換以及基本操作


  JAVA多線程實(shí)現(xiàn)的四種方式


  Java多線程學(xué)習(xí),深入解析


  常見Java多線程面試題總結(jié)


Java培訓(xùn) Java培訓(xùn)教程 Java教程

培訓(xùn)啦提醒您:交易時(shí)請(qǐng)核實(shí)對(duì)方資質(zhì),對(duì)于過大宣傳或承諾需謹(jǐn)慎!任何要求預(yù)付定金、匯款等方式均存在風(fēng)險(xiǎn),謹(jǐn)防上當(dāng)。