日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > java >内容正文

java

Java多线程系列(六):深入详解Synchronized同步锁的底层实现

發(fā)布時間:2024/7/5 java 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java多线程系列(六):深入详解Synchronized同步锁的底层实现 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

談到多線程就不得不談到Synchronized,很多同學(xué)只會使用,缺不是很明白整個Synchronized的底層實現(xiàn)原理,這也是面試經(jīng)常被問到的環(huán)節(jié),比如:

  • synchronized的底層實現(xiàn)原理
  • synchronized鎖與JVM的實現(xiàn)
  • synchronized鎖升級順序
  • synchronized鎖的優(yōu)劣勢與應(yīng)用場景
  • 今天主要分享以上內(nèi)容,詳解synchronized的底層實現(xiàn),多線程相關(guān)的可以參考:

    Java多線程系列教程:線程的五大狀態(tài),以及線程之間的通信與協(xié)作?

    Java多線程系列教程:Java線程池的使用方式,核心運行原理、以及注意事項

    最全Java鎖詳解:獨享鎖/共享鎖+公平鎖/非公平鎖+樂觀鎖/悲觀鎖?

    Java多線程系列教程:4種常用Java線程鎖的特點,性能比較、使用場景

    史上最強多線程面試44題和答案:線程鎖+線程池+線程同步等


    Synchronized

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

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

    Synchronized的使用

    1.synchronized的3種使用方式

    • 修飾實例方法:作用于當(dāng)前實例加鎖
    • 修飾靜態(tài)方法:作用于當(dāng)前類對象加鎖
    • 修飾代碼塊:指定加鎖對象,對給定對象加鎖

    2.synchronized的代碼范例

    Synchronized的底層實現(xiàn)


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

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


    1.Java對象頭


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

    • 對象頭(Header)
    • 實例數(shù)據(jù)(Instance Data)
    • 對齊填充(Padding)


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

    • 類型指針(Klass Pointer:是對象指向它的類元數(shù)據(jù)的指針,虛擬機通過這個指針來確定這個對象是哪個類的實例;
    • 標(biāo)記字段(Mark Word:用于存儲對象自身的運行時數(shù)據(jù),如哈希碼(HashCode)、GC分代年齡、鎖狀態(tài)標(biāo)志、線程持有的鎖、偏向線程 ID、偏向時間戳等等,它是實現(xiàn)輕量級鎖和偏向鎖的關(guān)鍵.


    2.Java鎖對象存儲位置


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


    3.Monitor

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

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

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

    4.線程狀態(tài)流轉(zhuǎn)在Monitor上體現(xiàn)

    描述為對象監(jiān)視器,當(dāng)多個線程同時請求某個對象監(jiān)視器時,對象監(jiān)視器會設(shè)置幾種狀態(tài)用來區(qū)分請求的線程:

    • Contention List:所有請求鎖的線程將被首先放置到該競爭隊列
    • Entry List:Contention List中那些有資格成為候選人的線程被移到Entry List
    • Wait Set:那些調(diào)用wait方法被阻塞的線程被放置到Wait Set
    • OnDeck:任何時刻最多只能有一個線程正在競爭鎖,該線程稱為OnDeck
    • Owner:獲得鎖的線程稱為Owner
    • !Owner:釋放鎖的線程

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



    Synchronized 鎖的升級順序

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


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


    1.偏向鎖

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

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


    2.輕量級鎖

    如果明顯存在其它線程申請鎖,那么偏向鎖將很快升級為輕量級鎖。


    3.自旋鎖

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


    4.重量級鎖

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



    偏向鎖、輕量級鎖、重量級鎖優(yōu)劣勢比較

    你可能也喜歡:

  • Java多線程系列(九):CountDownLatch、Semaphore等4大并發(fā)工具類詳解
  • Java多線程系列(四):4種常用Java線程鎖的特點,性能比較、使用場景
  • Java多線程系列(一):最全面的Java多線程學(xué)習(xí)概述
  • Java多線程系列(十):源碼剖析AQS的實現(xiàn)原理
  • Java多線程系列(七):并發(fā)容器的原理,7大并發(fā)容器詳解、及使用場景
  • Java多線程系列(八):ConcurrentHashMap的實現(xiàn)原理(JDK1.7和JDK1.8)

  • 總結(jié)

    以上是生活随笔為你收集整理的Java多线程系列(六):深入详解Synchronized同步锁的底层实现的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。