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

Java多線程中synchronized的工作原理

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

 1. 鎖的工作流程

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

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

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

舉例說明:

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

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

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

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

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

2. 偏向鎖

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

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

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

舉例:

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

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

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

3. 輕量級鎖和重量級鎖

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

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

3.1 輕量級鎖

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

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

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

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

3.2 重量級鎖

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

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

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

4.1 鎖消除

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

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

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

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

4.2 鎖粗化

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

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

舉例說明:

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

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

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

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

synchronized工作原理是什么?

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

什么是偏向鎖、輕量級鎖、重量級鎖?

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

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

相關(guān)文章

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

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

    這篇文章主要介紹了SpringBoot中集成screw(螺絲釘)實現(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)存泄漏是指無用對象持續(xù)占有內(nèi)存或無用對象的內(nèi)存得不到及時釋放,從而造成內(nèi)存空間的浪費(fèi)稱為內(nèi)存泄漏。長生命周期的對象持有短生命周期對象的引用就很可能發(fā)生內(nèi)存泄漏,盡管短生命周期對象已經(jī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)用鏈上的日志串起來,本文通過實例代碼給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧
    2025-01-01
  • maven 使用assembly 進(jìn)行打包的方法

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

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

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

    這篇文章主要介紹了MyBatis之動態(tài)SQL和緩存使用及說明,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    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集成測試遠(yuǎn)程連接Redis服務(wù)的教程詳解

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

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

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

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

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

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

最新評論

陕西省| 高淳县| 道孚县| 开封市| 靖边县| 云浮市| 石泉县| 句容市| 青州市| 婺源县| 古丈县| 中山市| 淳化县| 福贡县| 汤阴县| 吉木乃县| 霍林郭勒市| 大悟县| 漳州市| 寿光市| 红原县| 张家港市| 志丹县| 唐河县| 木兰县| 云南省| 上栗县| 隆昌县| 景宁| 台州市| 黄陵县| 紫阳县| 页游| 阿城市| 巴林左旗| 龙江县| 阿拉善左旗| 体育| 台南县| 紫云| 海晏县|