最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

 更新時(shí)間:2022年05月08日 15:38:55   作者:? Java中文社群?  ?  
這篇文章主要介紹了Java synchronized底層的實(shí)現(xiàn)原理,文章基于Java來(lái)介紹 synchronized 是如何運(yùn)行的,內(nèi)容詳細(xì)具有一定的參考價(jià)值,需要的小伙伴可以參考一下

前言:

想了解 synchronized 是如何運(yùn)行的?就要先搞清楚 synchronized 是如何實(shí)現(xiàn)? synchronized 同步鎖是通過(guò) JVM 內(nèi)置的 Monitor 監(jiān)視器實(shí)現(xiàn)的,而監(jiān)視器又是依賴操作系統(tǒng)的互斥鎖 Mutex 實(shí)現(xiàn)的,那接下來(lái)我們先來(lái)了解一下監(jiān)視器。

監(jiān)視器

監(jiān)視器是一個(gè)概念或者說(shuō)是一個(gè)機(jī)制,它用來(lái)保障在任何時(shí)候,只有一個(gè)線程能夠執(zhí)行指定區(qū)域的代碼。

一個(gè)監(jiān)視器像是一個(gè)建筑,建筑里有一個(gè)特殊的房間,這個(gè)房間同一時(shí)刻只能被一個(gè)線程所占有。一個(gè)線程從進(jìn)入該房間到離開(kāi)該房間,可以全程獨(dú)占該房間的所有數(shù)據(jù)。進(jìn)入該建筑叫做進(jìn)入監(jiān)視器(entering the monitor),進(jìn)入該房間叫做獲得監(jiān)視器(acquiring the monitor),獨(dú)自占有該房間叫做擁有監(jiān)視器(owning the monitor),離開(kāi)該房間叫做釋放監(jiān)視器(releasing the monitor),離開(kāi)該建筑叫做退出監(jiān)視器(exiting the monitor)。

嚴(yán)格意義來(lái)說(shuō)監(jiān)視器和鎖的概念是不同的,但很多地方也把二者相互指代。

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

下面我們?cè)诖a中添加一個(gè) synchronized 代碼塊,來(lái)觀察一下它在字節(jié)碼層面是如何實(shí)現(xiàn)的?

示例代碼如下:

public class SynchronizedToMonitorExample {
    public static void main(String[] args) {
        int count = 0;
        synchronized (SynchronizedToMonitorExample.class) {
            for (int i = 0; i < 10; i++) {
                count++;
            }
        }
        System.out.println(count);
    }
}

當(dāng)我們將上述代碼編譯成字節(jié)碼之后,得到的結(jié)果是這樣的: 

 從上述結(jié)果我們可以看出,在 main 方法中多了一對(duì) monitorenter 和 monitorexit 的指令,它們的含義是:

  • monitorenter:表示進(jìn)入監(jiān)視器。
  • monitorexit:表示退出監(jiān)視器。

由此可知 synchronized 是依賴 Monitor 監(jiān)視器實(shí)現(xiàn)的。

執(zhí)行流程

在 Java 中,synchronized 是非公平鎖,也是可以重入鎖。 所謂的非公平鎖是指,線程獲取鎖的順序不是按照訪問(wèn)的順序先來(lái)先到的,而是由線程自己競(jìng)爭(zhēng),隨機(jī)獲取到鎖。 可重入鎖指的是,一個(gè)線程獲取到鎖之后,可以重復(fù)得到該鎖。這些內(nèi)容是理解接下來(lái)內(nèi)容的前置知識(shí)。 在 HotSpot 虛擬機(jī)中,Monitor 底層是由 C++實(shí)現(xiàn)的,它的實(shí)現(xiàn)對(duì)象是 ObjectMonitor,ObjectMonitor 結(jié)構(gòu)體的實(shí)現(xiàn)如下:

ObjectMonitor::ObjectMonitor() {
  _header       = NULL;
  _count       = 0;
  _waiters      = 0,
  _recursions   = 0;       //線程的重入次數(shù)
  _object       = NULL;
  _owner        = NULL;    //標(biāo)識(shí)擁有該monitor的線程
  _WaitSet      = NULL;    //等待線程組成的雙向循環(huán)鏈表,_WaitSet是第一個(gè)節(jié)點(diǎn)
  _WaitSetLock  = 0 ;
  _Responsible  = NULL ;
  _succ         = NULL ;
  _cxq          = NULL ;    //多線程競(jìng)爭(zhēng)鎖進(jìn)入時(shí)的單向鏈表
  FreeNext      = NULL ;
  _EntryList    = NULL ;    //_owner從該雙向循環(huán)鏈表中喚醒線程結(jié)點(diǎn),_EntryList是第一個(gè)節(jié)點(diǎn)
  _SpinFreq     = 0 ;
  _SpinClock    = 0 ;
  OwnerIsThread = 0 ;
} 

在以上代碼中有幾個(gè)關(guān)鍵的屬性:

  • _count:記錄該線程獲取鎖的次數(shù)(也就是前前后后,這個(gè)線程一共獲取此鎖多少次)。
  • _recursions:鎖的重入次數(shù)。
  • _owner:The Owner 擁有者,是持有該 ObjectMonitor(監(jiān)視器)對(duì)象的線程;
  • _EntryList:EntryList 監(jiān)控集合,存放的是處于阻塞狀態(tài)的線程隊(duì)列,在多線程下,競(jìng)爭(zhēng)失敗的線程會(huì)進(jìn)入 EntryList 隊(duì)列。
  • _WaitSet:WaitSet 待授權(quán)集合,存放的是處于 wait 狀態(tài)的線程隊(duì)列,當(dāng)線程執(zhí)行了 wait() 方法之后,會(huì)進(jìn)入 WaitSet 隊(duì)列。

監(jiān)視器執(zhí)行的流程如下:

  • 線程通過(guò) CAS(對(duì)比并替換)嘗試獲取鎖,如果獲取成功,就將 _owner 字段設(shè)置為當(dāng)前線程,說(shuō)明當(dāng)前線程已經(jīng)持有鎖,并將 _recursions 重入次數(shù)的屬性 +1。如果獲取失敗則先通過(guò)自旋 CAS 嘗試獲取鎖,如果還是失敗則將當(dāng)前線程放入到 EntryList 監(jiān)控隊(duì)列(阻塞)。
  • 當(dāng)擁有鎖的線程執(zhí)行了 wait 方法之后,線程釋放鎖,將 owner 變量恢復(fù)為 null 狀態(tài),同時(shí)將該線程放入 WaitSet 待授權(quán)隊(duì)列中等待被喚醒。
  • 當(dāng)調(diào)用 notify 方法時(shí),隨機(jī)喚醒 WaitSet 隊(duì)列中的某一個(gè)線程,當(dāng)調(diào)用 notifyAll 時(shí)喚醒所有的 WaitSet 中的線程嘗試獲取鎖。
  • 線程執(zhí)行完釋放了鎖之后,會(huì)喚醒 EntryList 中的所有線程嘗試獲取鎖。

以上就是監(jiān)視器的執(zhí)行流程,執(zhí)行流程如下圖所示:

總結(jié)

synchronized 同步鎖是通過(guò) JVM 內(nèi)置的 Monitor 監(jiān)視器實(shí)現(xiàn)的,而監(jiān)視器又是依賴操作系統(tǒng)的互斥鎖 Mutex 實(shí)現(xiàn)的。JVM 監(jiān)視器的執(zhí)行流程是:線程先通過(guò)自旋 CAS 的方式嘗試獲取鎖,如果獲取失敗就進(jìn)入 EntrySet 集合,如果獲取成功就擁有該鎖。當(dāng)調(diào)用 wait() 方法時(shí),線程釋放鎖并進(jìn)入 WaitSet 集合,等其他線程調(diào)用 notify 或 notifyAll 方法時(shí)再嘗試獲取鎖。鎖使用完之后就會(huì)通知 EntrySet 集合中的線程,讓它們嘗試獲取鎖。

到此這篇關(guān)于Java synchronized底層的實(shí)現(xiàn)原理的文章就介紹到這了,更多相關(guān)Java synchronized內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 解決@Api注解不展示controller內(nèi)容的問(wèn)題

    解決@Api注解不展示controller內(nèi)容的問(wèn)題

    這篇文章主要介紹了解決@Api注解不展示controller內(nèi)容的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教。
    2022-01-01
  • java類中生成jfreechart,返回圖表的url地址 代碼分享

    java類中生成jfreechart,返回圖表的url地址 代碼分享

    這篇文章介紹了java類中生成jfreechart,返回圖表的url地址的代碼,有需要的朋友可以參考一下
    2013-08-08
  • Java?Lambda表達(dá)式常用的函數(shù)式接口

    Java?Lambda表達(dá)式常用的函數(shù)式接口

    這篇文章主要介紹了Java?Lambda表達(dá)式常用的函數(shù)式接口,文章基于Java?Lambda表達(dá)式展開(kāi)對(duì)常用的函數(shù)式接口的介紹,具有一的的參考價(jià)值需要的小伙伴可以參考一下
    2022-04-04
  • Java整合RabbitMQ實(shí)現(xiàn)五種常見(jiàn)消費(fèi)模型

    Java整合RabbitMQ實(shí)現(xiàn)五種常見(jiàn)消費(fèi)模型

    本文將深入介紹RabbitMQ的五種常見(jiàn)消費(fèi)模型,包括簡(jiǎn)單隊(duì)列模型、工作隊(duì)列模型、發(fā)布/訂閱模型、路由模型和主題模型,刪除線格式并探討它們各自的優(yōu)缺點(diǎn)和適用場(chǎng)景,感興趣的可以了解一下
    2023-11-11
  • Java 中的 String對(duì)象為什么是不可變的

    Java 中的 String對(duì)象為什么是不可變的

    String對(duì)象是不可變的,但這僅意味著你無(wú)法通過(guò)調(diào)用它的公有方法來(lái)改變它的值。本文給大家介紹java中的string對(duì)象為什么是不可變的,需要的朋友一起了解了解吧
    2015-10-10
  • Hadoop 中 HBase Shell命令的詳解

    Hadoop 中 HBase Shell命令的詳解

    這篇文章主要介紹了Hadoop 中 HBase Shell命令的詳解的相關(guān)資料,需要的朋友可以參考下
    2017-10-10
  • java圖形界面AWT編寫計(jì)算器

    java圖形界面AWT編寫計(jì)算器

    這篇文章主要為大家詳細(xì)介紹了基于java語(yǔ)言下圖形界面AWT編寫計(jì)算器,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-12-12
  • JavaSE實(shí)戰(zhàn)之酒店訂房系統(tǒng)的實(shí)現(xiàn)

    JavaSE實(shí)戰(zhàn)之酒店訂房系統(tǒng)的實(shí)現(xiàn)

    這篇文章主要為大家詳細(xì)介紹了如何利用JavaSE實(shí)現(xiàn)酒店訂房系統(tǒng),文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)JavaSE開(kāi)發(fā)有一定的幫助,需要的可以參考一下
    2022-07-07
  • 智能 AI 代碼生成工具 Cursor 安裝和使用超詳細(xì)教程

    智能 AI 代碼生成工具 Cursor 安裝和使用超詳細(xì)教程

    Cursor.so 是一個(gè)集成了 GPT-4 的國(guó)內(nèi)直接可以訪問(wèn)的,優(yōu)秀而強(qiáng)大的免費(fèi)代碼生成器,可以幫助你快速編寫、編輯和討論代碼,這篇文章主要介紹了智能 AI 代碼生成工具 Cursor 安裝和使用介紹,需要的朋友可以參考下
    2023-05-05
  • JAVA加密算法實(shí)密鑰一致協(xié)議代碼示例

    JAVA加密算法實(shí)密鑰一致協(xié)議代碼示例

    這篇文章主要介紹了JAVA加密算法實(shí)密鑰一致協(xié)議代碼示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-10-10

最新評(píng)論

东乡县| 北碚区| 新密市| 彰化市| 天镇县| 珲春市| 呼玛县| 伊通| 荃湾区| 横山县| 金塔县| 新民市| 临海市| 天水市| 台东市| 肇庆市| 介休市| 施秉县| 韶山市| 偏关县| 临澧县| 余江县| 馆陶县| 新田县| 米脂县| 莒南县| 历史| 南召县| 临夏县| 林西县| 慈利县| 札达县| 南通市| 马鞍山市| 浦江县| 澄迈县| 尖扎县| 五峰| 西昌市| 五家渠市| 玉田县|