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

Java多線程中synchronized的工作原理

 更新時(shí)間:2023年07月20日 10:23:58   作者:一只愛打拳的程序猿  
這篇文章主要介紹了Java多線程中synchronized的工作原理,本期講解 synchronized 工作的原理以及常見的鎖優(yōu)化機(jī)制,相信大家在看完這篇博文后對(duì) synchronized 工作流程有一定的理解,需要的朋友可以參考下

 1. 鎖的工作流程

眾所周知,synchronized 關(guān)鍵字是用來加鎖的,加鎖的原因就是多個(gè)線程搶占資源導(dǎo)致線程執(zhí)行的過程不具備原子性。

JVM 將 synchronized 加鎖的過程分為四個(gè)狀態(tài)分為無鎖、偏向鎖、輕量級(jí)鎖、重量級(jí)鎖。

剛開始是無鎖狀態(tài),加上鎖后處于偏向鎖狀態(tài),鎖有了競(jìng)爭(zhēng)鎖升級(jí)為輕量級(jí)鎖,鎖的競(jìng)爭(zhēng)更加激烈了升級(jí)為重量級(jí)鎖狀態(tài)。

舉例說明:

有個(gè)女孩叫如花,有個(gè)男孩叫阿三,如花是個(gè)漂亮的女孩,阿三是個(gè)帥氣又有錢的男孩。

阿三追求如花,如花不想確定情侶關(guān)系也不想放棄阿三,于是如花吊著阿三,此時(shí)就處于一個(gè)偏向鎖狀態(tài)。阿三就像鎖,鎖的競(jìng)爭(zhēng)不激烈,如花有恃無恐,鎖處于 偏向鎖 狀態(tài)。

某一天,如花發(fā)現(xiàn)阿三正在被其他女孩追求,如花慌了立馬跟張三確定男女關(guān)系,此時(shí)就處于輕量級(jí)鎖狀態(tài)。鎖的競(jìng)爭(zhēng)激烈了,鎖升級(jí)為 輕量級(jí)鎖。

隨著日子一天天過去,越來越多女孩開始愛慕阿三。如花更加緊張了,生怕張三離開她,于是越來越限制張三的自由了,此時(shí)就處于重量級(jí)鎖狀態(tài)。鎖的競(jìng)爭(zhēng)更加激烈了,鎖升級(jí)為 輕量級(jí)鎖。

在上述例子中,阿三為鎖,如花為 JVM。JVM 通過鎖的競(jìng)爭(zhēng)程度,來決定鎖的策略是什么。

2. 偏向鎖

第一嘗試獲取鎖的線程,優(yōu)先處于偏向鎖的狀態(tài)。此時(shí)這個(gè)線程并未進(jìn)行加鎖操作,而是通過一個(gè) 標(biāo)記 來確定這是第一次獲取鎖的線程。

如果代碼在整個(gè)運(yùn)行過程中,沒有遇到其他線程來競(jìng)爭(zhēng)鎖。就不會(huì)進(jìn)行加鎖了。但,如果有線程進(jìn)行競(jìng)爭(zhēng)鎖,此時(shí)偏向鎖就會(huì)變成一把真正的鎖(輕量級(jí)鎖)。

偏向鎖,主要體現(xiàn)能不加鎖就不加鎖這個(gè)概念,它實(shí)際上并沒有加鎖只是通過一個(gè)標(biāo)記來確定鎖于無競(jìng)爭(zhēng)狀態(tài),等到鎖有競(jìng)爭(zhēng)情況發(fā)生了,偏向鎖才會(huì)變成一把鎖(輕量級(jí)鎖)。

舉例:

21世紀(jì)流行著這樣一段關(guān)系:

有一個(gè)男孩小強(qiáng)和一個(gè)女孩小美,小強(qiáng)是一把鎖,小美是一個(gè)線程。小強(qiáng)和小美想過著夫妻一般的生活但不去領(lǐng)證。此時(shí),小美在使用這把鎖的時(shí)候鎖的狀態(tài)為偏向鎖,因?yàn)闆]有其他線程競(jìng)爭(zhēng)這把鎖。

某一天,小強(qiáng)在公司認(rèn)識(shí)了一個(gè)女孩小宣,小宣是一個(gè)線程。小宣愛慕小強(qiáng),于是追求他。小美不想小強(qiáng)被搶走,于是和小強(qiáng)結(jié)婚(領(lǐng)證)。此時(shí),小美使用小強(qiáng)這把鎖就變成了輕量級(jí)鎖狀態(tài)。最后小強(qiáng)只得對(duì)小宣說:“你是個(gè)好女孩,我配不上你”。

3. 輕量級(jí)鎖和重量級(jí)鎖

輕量級(jí)鎖為了避免進(jìn)入同步狀態(tài),采用了一些基于CAS操作的優(yōu)化手段,但如果線程CAS操作失敗并達(dá)到一定次數(shù)后,會(huì)進(jìn)入自旋鎖狀態(tài)等待獲取鎖。但如果自旋等待的時(shí)間過長(zhǎng),就需要升級(jí)為重量級(jí)鎖,這是為了讓其它線程有機(jī)會(huì)搶到鎖。

升級(jí)為重量級(jí)鎖后,會(huì)將當(dāng)前線程阻塞并進(jìn)入內(nèi)核態(tài),而不再直接進(jìn)入自旋鎖狀態(tài)等待,這樣可以避免浪費(fèi)CPU資源。同時(shí),重量級(jí)鎖在釋放鎖的時(shí)候,也需要進(jìn)行內(nèi)核態(tài)的操作,因此其釋放鎖的代價(jià)相對(duì)較高。

3.1 輕量級(jí)鎖

通過上文講解,我們了解到隨著其他線程競(jìng)爭(zhēng)鎖,鎖由偏向鎖狀態(tài)升級(jí)為輕量級(jí)鎖狀態(tài)。輕量級(jí)鎖狀態(tài),實(shí)際上就是自適應(yīng)的自旋鎖狀態(tài)。

此處的輕量級(jí)鎖,是通過 CAS 機(jī)制來實(shí)現(xiàn)的:

通過 CAS 機(jī)制檢查并且更新一塊內(nèi)存。如果更新成功,則加鎖成功。更新失敗,則認(rèn)為鎖被占用,繼續(xù)自旋式的等待。

自旋式,就是通過一個(gè)循環(huán)來判定鎖是否被占用。如果鎖被占用此時(shí)會(huì)無限循環(huán),直到鎖不被占用退出循環(huán)。在此期間,自選鎖一直占用著 CPU 資源,比較浪費(fèi)。

3.2 重量級(jí)鎖

如果鎖競(jìng)爭(zhēng)愈發(fā)激烈,自旋鎖不能快速獲取到鎖的狀態(tài),就會(huì)升級(jí)為重量級(jí)鎖。此時(shí)的重量級(jí)鎖會(huì)引申到內(nèi)核態(tài)與用戶態(tài)。

4. 常見的鎖優(yōu)化

常見的鎖優(yōu)化有兩種:鎖消除于鎖粗化。請(qǐng)看下方講解。

4.1 鎖消除

鎖消除是一種編譯器優(yōu)化機(jī)制,當(dāng)代碼塊被 synchronized 鎖住時(shí)。

如果該代碼塊只被某一線程獨(dú)占則 synchronized 就被編譯器消除了,因?yàn)榫幾g器會(huì)檢查并認(rèn)為該代碼塊并不需要加鎖,也就是我們所說的鎖被消除了。

當(dāng)然,多個(gè)線程使用多把鎖時(shí),只要互不干擾各自使用各自的鎖資源,這種情況鎖也會(huì)被消除。

鎖消除是一種優(yōu)化技術(shù),它可以減少不必要的鎖操作對(duì)性能的影響,提高程序的執(zhí)行效率,節(jié)省系統(tǒng)消耗的資源。

4.2 鎖粗化

談到鎖粗化,我們會(huì)聯(lián)想到一個(gè)“粒度感”,代碼越多粒度越粗,代碼越少粒度越細(xì)。在寫代碼的過程中,我們很難兼容到要保證代碼少又要保證代碼好。

比如在某個(gè)場(chǎng)景下,我們頻繁的使用 加鎖/解鎖 操作,編譯器會(huì)通過優(yōu)化手段將這些頻繁的 加鎖解鎖 進(jìn)行粗化,這樣就能大大減小系統(tǒng)開銷,也就是我們所說的鎖粗化。

舉例說明:

在公司上班,老板上午安排了一個(gè)任務(wù)給我,下午安排了個(gè)任務(wù)給我,晚上又安排了一個(gè)任務(wù)給我,要求我明天晚上之前要完成。

如果我今天下午完成第一個(gè)任務(wù)打電話給老板并匯報(bào)工作,明天上午完成了第二個(gè)任務(wù)再打電話給老板,明天晚上完成了第三個(gè)任務(wù)又打電話給老板。

老板心里肯定想,這人煩不煩一起給我不就得了。(當(dāng)然,在任務(wù)不緊急的情況下)

如果我一次性匯報(bào)三個(gè)任務(wù),此時(shí)就大大減少了老板接電話(上鎖)掛電話(解鎖)的開銷。

synchronized工作原理是什么?

synchronized 剛開始是無鎖的狀態(tài),當(dāng) synchronized 所修飾的資源被線程獨(dú)占后就升級(jí)為偏向鎖狀態(tài),當(dāng) synchronized 被多個(gè)線程競(jìng)爭(zhēng)后就升級(jí)為輕量級(jí)鎖,鎖的競(jìng)爭(zhēng)越來越激烈并且鎖釋放得很慢此時(shí)就會(huì)升級(jí)為重量級(jí)鎖狀態(tài)。

什么是偏向鎖、輕量級(jí)鎖、重量級(jí)鎖?

  • 偏向鎖:第一個(gè)使用到鎖的線程,此時(shí)并未進(jìn)行鎖操作,編譯器會(huì)使用一個(gè)標(biāo)識(shí)來確定這個(gè)鎖只被一個(gè)線程使用。
  • 輕量級(jí)鎖:當(dāng)鎖被多個(gè)線程競(jìng)爭(zhēng)了,此時(shí)鎖會(huì)從偏向鎖升級(jí)為輕量級(jí)鎖,輕量級(jí)鎖會(huì)通過 CAS 機(jī)制即自旋操作,來無限循環(huán)嘗試獲取鎖直到獲取到鎖為止。因此,在獲取到鎖之前會(huì)一直占用CPU資源,容易浪費(fèi)資源。
  • 重量級(jí)鎖:當(dāng)鎖競(jìng)爭(zhēng)激烈并且鎖資源釋放過慢,此時(shí)鎖會(huì)中輕量級(jí)鎖升級(jí)為重量級(jí)鎖,重量級(jí)鎖會(huì)跟隨系統(tǒng)的調(diào)度不再進(jìn)行自旋等待,直到鎖釋放了,再參與鎖的競(jìng)爭(zhēng),大大減少了系統(tǒng)資源的浪費(fèi)。

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

相關(guān)文章

  • SpringBoot中集成screw(螺絲釘)實(shí)現(xiàn)數(shù)據(jù)庫表結(jié)構(gòu)文檔生成方法

    SpringBoot中集成screw(螺絲釘)實(shí)現(xiàn)數(shù)據(jù)庫表結(jié)構(gòu)文檔生成方法

    這篇文章主要介紹了SpringBoot中集成screw(螺絲釘)實(shí)現(xiàn)數(shù)據(jù)庫表結(jié)構(gòu)文檔生成,下面以連接mysql數(shù)據(jù)庫并生成html格式的數(shù)據(jù)庫結(jié)構(gòu)文檔為例,插件的使用方式除可以使用代碼外,還可以使用Maven插件的方式,需要的朋友可以參考下
    2024-07-07
  • Java怎樣創(chuàng)建集合才能避免造成內(nèi)存泄漏你了解嗎

    Java怎樣創(chuàng)建集合才能避免造成內(nèi)存泄漏你了解嗎

    內(nèi)存泄漏是指無用對(duì)象持續(xù)占有內(nèi)存或無用對(duì)象的內(nèi)存得不到及時(shí)釋放,從而造成內(nèi)存空間的浪費(fèi)稱為內(nèi)存泄漏。長(zhǎng)生命周期的對(duì)象持有短生命周期對(duì)象的引用就很可能發(fā)生內(nèi)存泄漏,盡管短生命周期對(duì)象已經(jīng)不再需要,但是因?yàn)殚L(zhǎng)生命周期持有它的引用而導(dǎo)致不能被回收
    2021-09-09
  • 詳解SpringMVC中的異常處理

    詳解SpringMVC中的異常處理

    這篇文章主要介紹了SpringMVC中的異常處理的相關(guān)資料,幫助大家更好的理解和學(xué)習(xí)使用SpringMVC,感興趣的朋友可以了解下
    2021-03-03
  • SpringBoot如何使用TraceId日志鏈路追蹤

    SpringBoot如何使用TraceId日志鏈路追蹤

    文章介紹了如何使用TraceId進(jìn)行日志鏈路追蹤,通過在日志中添加TraceId關(guān)鍵字,可以將同一次業(yè)務(wù)調(diào)用鏈上的日志串起來,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧
    2025-01-01
  • maven 使用assembly 進(jìn)行打包的方法

    maven 使用assembly 進(jìn)行打包的方法

    這篇文章主要介紹了maven 使用assembly 進(jìn)行打包的方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-09-09
  • MyBatis之動(dòng)態(tài)SQL和緩存使用及說明

    MyBatis之動(dòng)態(tài)SQL和緩存使用及說明

    這篇文章主要介紹了MyBatis之動(dòng)態(tài)SQL和緩存使用及說明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2026-05-05
  • Java9新特性Java.util.Optional優(yōu)化與增強(qiáng)解析

    Java9新特性Java.util.Optional優(yōu)化與增強(qiáng)解析

    這篇文章主要為大家介紹了Java9新特性Java.util.Optional優(yōu)化與增強(qiáng)使用說明解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步
    2022-03-03
  • 基于SpringBoot集成測(cè)試遠(yuǎn)程連接Redis服務(wù)的教程詳解

    基于SpringBoot集成測(cè)試遠(yuǎn)程連接Redis服務(wù)的教程詳解

    這篇文章主要介紹了基于SpringBoot集成測(cè)試遠(yuǎn)程連接的Redis服務(wù)的相關(guān)知識(shí),本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-03-03
  • Java動(dòng)態(tài)顯示當(dāng)前日期和時(shí)間

    Java動(dòng)態(tài)顯示當(dāng)前日期和時(shí)間

    這篇文章主要為大家詳細(xì)介紹了Java動(dòng)態(tài)顯示當(dāng)前日期和時(shí)間,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-12-12
  • Netty粘包問題的常見解決方案

    Netty粘包問題的常見解決方案

    粘包和拆包問題也叫做粘包和半包問題,它是指在數(shù)據(jù)傳輸時(shí),接收方未能正常讀取到一條完整數(shù)據(jù)的情況(只讀取了部分?jǐn)?shù)據(jù),或多讀取到了另一條數(shù)據(jù)的情況)就叫做粘包或拆包問題,本文介紹了Netty如何解決粘包問題,需要的朋友可以參考下
    2024-06-06

最新評(píng)論

金平| 农安县| 永嘉县| 南丰县| 日喀则市| 桂平市| 遂川县| 民勤县| 防城港市| 永吉县| 四子王旗| 威海市| 东安县| 河源市| 遂宁市| 渑池县| 株洲市| 韩城市| 卓资县| 兴隆县| 宽城| 海南省| 贡嘎县| 宕昌县| 肥东县| 高碑店市| 南江县| 九台市| 贺兰县| 恩平市| 哈尔滨市| 宁武县| 惠州市| 南汇区| 双柏县| 于都县| 永仁县| 逊克县| 永善县| 平山县| 崇仁县|