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

深入詳解Java中synchronized鎖升級(jí)的套路

 更新時(shí)間:2023年04月14日 10:12:57   作者:奔跑的毛球  
synchronized鎖是啥?鎖其實(shí)就是一個(gè)對(duì)象,隨便哪一個(gè)都可以,Java中所有的對(duì)象都是鎖,換句話說,Java中所有對(duì)象都可以成為鎖。本文我們主要來聊聊synchronized鎖升級(jí)的套路,感興趣的可以收藏一下

synchronized鎖是啥?鎖其實(shí)就是一個(gè)對(duì)象,隨便哪一個(gè)都可以,Java中所有的對(duì)象都是鎖,換句話說,Java中所有對(duì)象都可以成為鎖。
這次我們主要聊的是synchronized鎖升級(jí)的套路

synchronized會(huì)經(jīng)歷四個(gè)階段:無鎖狀態(tài)、偏向鎖、輕量級(jí)鎖、重量級(jí)鎖依次從耗費(fèi)資源最少,性能最高,到耗費(fèi)資源多,性能最差。

鎖原理

先看看這些狀態(tài)的鎖為什么稱之為鎖,他們的互斥原理是啥。

偏向鎖

當(dāng)一個(gè)線程到達(dá)同步代碼塊,嘗試獲取鎖對(duì)象的時(shí)候,會(huì)查看對(duì)象頭中的MarkWord里的線程ID,如果這里沒有ID則將自己的保存進(jìn)去,拿到鎖。若是有,則查看是否是當(dāng)前線程,如果不是,就CAS嘗試改,如果是,就已經(jīng)拿到了鎖資源。

這里詳細(xì)說說CAS嘗試修改的邏輯:它會(huì)檢查持有偏向鎖的線程狀態(tài)。首先遍歷當(dāng)前JVM的所有存活的線程,如果能找到偏向的線程,則說明偏向的線程還存活,此時(shí)會(huì)檢查線程是否在執(zhí)行同步代碼塊中的代碼,如果是,則升級(jí)為輕量級(jí)鎖,去繼續(xù)進(jìn)行CAS競(jìng)爭(zhēng)鎖。所以加了偏向鎖之后,同時(shí)只有一個(gè)線程可以拿到鎖執(zhí)行同步代碼塊中的代碼。

輕量級(jí)鎖

查看對(duì)象頭中的MarkWord里的Lock Record指針指向的是否是當(dāng)前線程的虛擬機(jī)棧,如果是,拿鎖執(zhí)行業(yè)務(wù),如果不是則進(jìn)行CAS,嘗試修改,若是修改幾次都沒有成功,再升級(jí)到重量級(jí)鎖。

重量級(jí)鎖

查看對(duì)象頭中的MarkWord里的指向的ObjectMonitor,查看owner是否是當(dāng)前線程,如果不是,扔到ObjectMonitor里的EntryList中排隊(duì),并掛起線程,等待被喚醒。

鎖升級(jí)

無鎖

一般情況下,新new出來的一個(gè)對(duì)象,暫時(shí)就是無鎖狀態(tài)。因?yàn)槠蜴i默認(rèn)是有延遲的,在啟動(dòng)JVM的前4s中,不存在偏向鎖,但是如果關(guān)閉了偏向鎖延遲的設(shè)置,new出來的對(duì)象,就會(huì)添加一個(gè)匿名偏向鎖。也就是說這個(gè)對(duì)象想找一個(gè)線程去增加偏向鎖,但是沒有找到,稱之為匿名偏向。存儲(chǔ)的線程ID為一堆0000,也沒有任何地址信息。

我們可以通過以下配置關(guān)閉偏向鎖延遲。

//關(guān)閉偏向鎖延遲的指令
-XX:BiasedLockingStartuoDelay=0

偏向鎖

當(dāng)某一個(gè)線程來獲取這個(gè)鎖資源時(shí),此時(shí)會(huì)成功獲取到,就會(huì)變?yōu)槠蜴i,偏向鎖存儲(chǔ)線程的ID。

當(dāng)偏向鎖升級(jí)時(shí),會(huì)觸發(fā)偏向鎖撤銷,偏向鎖撤銷需要等到一個(gè)安全點(diǎn),比如GC的時(shí)候,偏向鎖撤銷的成本太高,所以默認(rèn)開始時(shí),會(huì)做偏向鎖延遲。若是直接有多個(gè)線程競(jìng)爭(zhēng),會(huì)跳過偏向鎖,直接變?yōu)檩p量級(jí)鎖。

細(xì)說一下偏向鎖撤銷的過程,成本為啥高呢?當(dāng)一個(gè)線程拿到偏向鎖之后,會(huì)把鎖的對(duì)象頭的Mark Work中的線程id指向自己,當(dāng)又有一個(gè)線程來了進(jìn)行爭(zhēng)搶導(dǎo)致鎖升級(jí)的的時(shí)候,會(huì)暫停之前拿到偏向鎖的線程,然后清空Mark Work中的線程id,增加一個(gè)輕量級(jí)鎖,然后再恢復(fù)暫停的線程繼續(xù)執(zhí)行。這也是為什么等到安全點(diǎn)再執(zhí)行鎖升級(jí)的原因,因?yàn)橐獣和>€程。

常見的安全點(diǎn):

  • 執(zhí)行GC的時(shí)候
  • 方法返回之前
  • 調(diào)用某個(gè)方法之后
  • 拋出異常的位置
  • 一個(gè)循環(huán)的末尾

輕量級(jí)鎖

當(dāng)在出現(xiàn)了多個(gè)線程的競(jìng)爭(zhēng),就會(huì)升級(jí)為輕量級(jí)鎖,輕量級(jí)鎖的效果就是基于CAS嘗試獲取鎖資源,這里會(huì)用到自適應(yīng)自旋鎖,根據(jù)上次CAS成功與否,耗費(fèi)的時(shí)間,決定這次自旋多少次。

輕量級(jí)鎖適用于競(jìng)爭(zhēng)不是很激烈的場(chǎng)景,一個(gè)線程拿到鎖,執(zhí)行同步代碼塊,很快就處理完了。再來一個(gè)線程嘗試一兩次也拿到了鎖,再去執(zhí)行,不會(huì)讓一個(gè)線程等待很久。

重量級(jí)鎖

如果到了重量級(jí)鎖,那就沒啥說的了,如果有線程持有鎖,其他想拿鎖的就掛起,等待鎖釋放后被依次喚醒。

鎖粗化&鎖消除

鎖粗化/鎖膨脹

鎖膨脹是編譯Java文件的時(shí)候,JIT幫我們做的優(yōu)化,它會(huì)減少鎖的獲取和釋放次數(shù)。 比如:

while(){
   synchronized(){
      // 多次的獲取和釋放,成本太高,會(huì)被優(yōu)化為下面這種
   }
}
synchronized(){
   while(){
       //  拿到鎖后執(zhí)行循環(huán),只加鎖和釋放一次
   }
}

鎖消除

鎖消除則是在一個(gè)加鎖的同步代碼塊中,沒有任何共享資源,也不存在鎖競(jìng)爭(zhēng)的情況,JIT編譯時(shí),就直接將鎖的指令優(yōu)化掉。 比如

synchronized(){
   int a = 1;
   a++;
   //操作局部變量的邏輯
}

到此這篇關(guān)于深入詳解Java中synchronized鎖升級(jí)的套路的文章就介紹到這了,更多相關(guān)Java synchronized鎖升級(jí)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java編程學(xué)習(xí)的幾個(gè)典型實(shí)例詳解

    Java編程學(xué)習(xí)的幾個(gè)典型實(shí)例詳解

    這篇文章主要給大家介紹了Java編程學(xué)習(xí)的幾個(gè)典型實(shí)例,其中包括模擬酒店房間管理系統(tǒng)、螺旋矩陣 例或者百雞問題的變形等經(jīng)典實(shí)例,具體來一起看詳細(xì)內(nèi)容吧,需要的朋友可以參考學(xué)習(xí)。
    2017-02-02
  • 基于java的opencv開發(fā)過程詳解

    基于java的opencv開發(fā)過程詳解

    這篇文章主要介紹了基于java的opencv開發(fā)過程詳解,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-04-04
  • springboot項(xiàng)目不同環(huán)境的配置讀取方式

    springboot項(xiàng)目不同環(huán)境的配置讀取方式

    SpringBoot支持application.properties、application.yml、application.yaml三種配置文件類型,可同時(shí)存在并合并配置,配置文件的讀取優(yōu)先級(jí)為:application.properties > application.yml > application.yaml,不同位置的相同類型配置文件
    2024-11-11
  • 關(guān)于Java實(shí)體類Serializable序列化接口的作用和必要性解析

    關(guān)于Java實(shí)體類Serializable序列化接口的作用和必要性解析

    序列化是將對(duì)象狀態(tài)轉(zhuǎn)化為可保持或者傳輸?shù)母袷竭^程,與序列化相反的是反序列化,完成序列化和反序列化,可以存儲(chǔ)或傳輸數(shù)據(jù),一般情況下,在定義實(shí)體類時(shí)會(huì)使用Serializable,需要的朋友可以參考下
    2023-05-05
  • Spring為singleton?bean注入prototype?bean

    Spring為singleton?bean注入prototype?bean

    這篇文章主要介紹了Spring為singleton?bean注入prototype?bean,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下
    2022-07-07
  • java如何對(duì)map進(jìn)行排序詳解(map集合的使用)

    java如何對(duì)map進(jìn)行排序詳解(map集合的使用)

    這篇文章主要介紹了java如何對(duì)map進(jìn)行排序,java map集合的使用詳解,大家可以參考使用
    2013-12-12
  • Spring?Boot?3?整合?MinIO?實(shí)現(xiàn)分布式文件存儲(chǔ)的全過程

    Spring?Boot?3?整合?MinIO?實(shí)現(xiàn)分布式文件存儲(chǔ)的全過程

    本文介紹了如何使用SpringBoot3和MinIO實(shí)現(xiàn)分布式文件存儲(chǔ),通過MinIO的分布式對(duì)象存儲(chǔ)系統(tǒng),可以解決傳統(tǒng)單機(jī)文件存儲(chǔ)方案在面對(duì)大規(guī)模數(shù)據(jù)和高并發(fā)訪問時(shí)的不足,文章詳細(xì)講解了MinIO的安裝、配置和使用,感興趣的朋友一起看看吧
    2025-03-03
  • Java中的Caffeine加載與驅(qū)逐策略詳解

    Java中的Caffeine加載與驅(qū)逐策略詳解

    這篇文章主要介紹了Java中的Caffeine加載與驅(qū)逐策略詳解,Caffeine是基于Java 8的高性能緩存庫,可提供接近最佳的命中率,Caffeine與ConcurrentMap相應(yīng),但是不完全相同,本文主要介紹Caffeine,需要的朋友可以參考下
    2023-10-10
  • 自定義類加載器以及打破雙親委派模型解析

    自定義類加載器以及打破雙親委派模型解析

    這篇文章主要介紹了自定義類加載器以及打破雙親委派模型解析,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-11-11
  • 使用java的HttpClient實(shí)現(xiàn)多線程并發(fā)

    使用java的HttpClient實(shí)現(xiàn)多線程并發(fā)

    這篇文章主要介紹了使用java的HttpClient實(shí)現(xiàn)多線程并發(fā)的相關(guān)資料,需要的朋友可以參考下
    2016-09-09

最新評(píng)論

贵州省| 阿克陶县| 肥城市| 岳池县| 公主岭市| 麻城市| 互助| 遵义县| 丹寨县| 井陉县| 兴安盟| 霍州市| 宁城县| 张家港市| 文登市| 历史| 静宁县| 巧家县| 南充市| 沈丘县| 木兰县| 万盛区| 安庆市| 司法| 天柱县| 岱山县| 中超| 海门市| 班戈县| 龙泉市| 武汉市| 龙州县| 离岛区| 吴江市| 句容市| 益阳市| 阳新县| 金沙县| 赫章县| 深圳市| 来宾市|