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

Java中synchronized?的4個優(yōu)化技巧

 更新時間:2022年05月20日 08:50:11   作者:??Java中文社群????  
本文主要介紹了Java中synchronized的4個優(yōu)化技巧,synchronized在JDK?1.5?時性能是比較低的,然而在后續(xù)的版本中經(jīng)過各種優(yōu)化迭代,它的性能也得到了前所未有的提升,下文更多相關(guān)資料需要的小伙伴可以參考一下

前言

synchronized 在 JDK 1.5 時性能是比較低的,然而在后續(xù)的版本中經(jīng)過各種優(yōu)化迭代,它的性能也得到了前所未有的提升,上一篇文章我們談到了鎖膨脹對 synchronized 性能的提升,然而它也只是“眾多” synchronized 性能優(yōu)化方案中的一種,那么我們本文就來盤點一下 synchronized 的核心優(yōu)化方案。

synchronized 核心優(yōu)化方案主要包含以下 4 個:

  • 鎖膨脹
  • 鎖消除
  • 鎖粗化
  • 自適應(yīng)自旋鎖

1.鎖膨脹

我們先來回顧一下鎖膨脹對 synchronized 性能的影響,所謂的鎖膨脹是指 synchronized 從無鎖升級到偏向鎖,再到輕量級鎖,最后到重量級鎖的過程,它叫做鎖膨脹也叫做鎖升級。 

 JDK 1.6 之前,synchronized 是重量級鎖,也就是說 synchronized 在釋放和獲取鎖時都會從用戶態(tài)轉(zhuǎn)換成內(nèi)核態(tài),而轉(zhuǎn)換的效率是比較低的。但有了鎖膨脹機(jī)制之后,synchronized 的狀態(tài)就多了無鎖、偏向鎖以及輕量級鎖了,這時候在進(jìn)行并發(fā)操作時,大部分的場景都不需要用戶態(tài)到內(nèi)核態(tài)的轉(zhuǎn)換了,這樣就大幅的提升了 synchronized 的性能。

PS:至于為什么不需要用戶態(tài)到內(nèi)核態(tài)的轉(zhuǎn)換?請移步到鎖膨脹的那篇文章:《Java中的synchronized 優(yōu)化方法之鎖膨脹機(jī)制》。

2.鎖消除

很多人都了解 synchronized 中鎖膨脹的機(jī)制,但對接下來的 3 項優(yōu)化卻知之甚少,這樣會在面試中錯失良機(jī),那么我們本文就把這 3 項優(yōu)化單獨拎出來講一下吧。

鎖消除指的是在某些情況下,JVM 虛擬機(jī)如果檢測不到某段代碼被共享和競爭的可能性,就會將這段代碼所屬的同步鎖消除掉,從而到底提高程序性能的目的。

鎖消除的依據(jù)是逃逸分析的數(shù)據(jù)支持,如 StringBuffer 的 append() 方法,或 Vector 的 add() 方法,在很多情況下是可以進(jìn)行鎖消除的,

比如以下這段代碼:

public String method() {
    StringBuffer sb = new StringBuffer();
    for (int i = 0; i < 10; i++) {
        sb.append("i:" + i);
    }
    return sb.toString();
}

以上代碼經(jīng)過編譯之后的字節(jié)碼如下: 

 從上述結(jié)果可以看出,之前我們寫的線程安全的加鎖的 StringBuffer 對象,在生成字節(jié)碼之后就被替換成了不加鎖不安全的 StringBuilder 對象了,原因是 StringBuffer 的變量屬于一個局部變量,并且不會從該方法中逃逸出去,所以此時我們就可以使用鎖消除(不加鎖)來加速程序的運(yùn)行。

3.鎖粗化

鎖粗化是指,將多個連續(xù)的加鎖、解鎖操作連接在一起,擴(kuò)展成一個范圍更大的鎖。

我只聽說鎖“細(xì)化”可以提高程序的執(zhí)行效率,也就是將鎖的范圍盡可能縮小,這樣在鎖競爭時,等待獲取鎖的線程才能更早的獲取鎖,從而提高程序的運(yùn)行效率,但鎖粗化是如何提高性能的呢?

沒錯,鎖細(xì)化的觀點在大多數(shù)情況下都是成立了,但是一系列連續(xù)加鎖和解鎖的操作,也會導(dǎo)致不必要的性能開銷,從而影響程序的執(zhí)行效率,比如這段代碼:

public String method() {
    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < 10; i++) {
        // 偽代碼:加鎖操作
        sb.append("i:" + i);
        // 偽代碼:解鎖操作
    }
    return sb.toString();
}

這里我們不考慮編譯器優(yōu)化的情況,如果在 for 循環(huán)中定義鎖,那么鎖的范圍很小,但每次 for 循環(huán)都需要進(jìn)行加鎖和釋放鎖的操作,性能是很低的;但如果我們直接在 for 循環(huán)的外層加一把鎖,那么對于同一個對象操作這段代碼的性能就會提高很多,

如下偽代碼所示:

public String method() {
    StringBuilder sb = new StringBuilder();
    // 偽代碼:加鎖操作
    for (int i = 0; i < 10; i++) {
        sb.append("i:" + i);
    }
    // 偽代碼:解鎖操作
    return sb.toString();
}

鎖粗化的作用:如果檢測到同一個對象執(zhí)行了連續(xù)的加鎖和解鎖的操作,則會將這一系列操作合并成一個更大的鎖,從而提升程序的執(zhí)行效率。

4.自適應(yīng)自旋鎖

自旋鎖是指通過自身循環(huán),嘗試獲取鎖的一種方式,偽代碼實現(xiàn)如下:

// 嘗試獲取鎖
while(!isLock()){
}

自旋鎖優(yōu)點在于它避免一些線程的掛起和恢復(fù)操作,因為掛起線程和恢復(fù)線程都需要從用戶態(tài)轉(zhuǎn)入內(nèi)核態(tài),這個過程是比較慢的,所以通過自旋的方式可以一定程度上避免線程掛起和恢復(fù)所造成的性能開銷。

但是,如果長時間自旋還獲取不到鎖,那么也會造成一定的資源浪費(fèi),所以我們通常會給自旋設(shè)置一個固定的值來避免一直自旋的性能開銷。然而對于 synchronized 關(guān)鍵字來說,它的自旋鎖更加的“智能”,synchronized 中的自旋鎖是自適應(yīng)自旋鎖,這就好比之前一直開的手動擋的三輪車,而經(jīng)過了 JDK 1.6 的優(yōu)化之后,我們的這部“車”,一下子變成自動擋的蘭博基尼了。 

自適應(yīng)自旋鎖是指,線程自旋的次數(shù)不再是固定的值,而是一個動態(tài)改變的值,這個值會根據(jù)前一次自旋獲取鎖的狀態(tài)來決定此次自旋的次數(shù)。比如上一次通過自旋成功獲取到了鎖,那么這次通過自旋也有可能會獲取到鎖,所以這次自旋的次數(shù)就會增多一些,而如果上一次通過自旋沒有成功獲取到鎖,那么這次自旋可能也獲取不到鎖,所以為了避免資源的浪費(fèi),就會少循環(huán)或者不循環(huán),以提高程序的執(zhí)行效率。簡單來說,如果線程自旋成功了,則下次自旋的次數(shù)會增多,如果失敗,下次自旋的次數(shù)會減少。

總結(jié)

本文我們介紹了 4 種優(yōu)化 synchronized 的方案,其中鎖膨脹和自適應(yīng)自旋鎖是 synchronized 關(guān)鍵字自身的優(yōu)化實現(xiàn),而鎖消除和鎖粗化是 JVM 虛擬機(jī)對 synchronized 提供的優(yōu)化方案,這些優(yōu)化方案最終使得 synchronized 的性能得到了大幅的提升,也讓它在并發(fā)編程中占據(jù)了一席之地。

到此這篇關(guān)于Java中synchronized 的4個優(yōu)化技巧的文章就介紹到這了,更多相關(guān)synchronized 優(yōu)化內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 淺談Java編程中的單例設(shè)計模式

    淺談Java編程中的單例設(shè)計模式

    這篇文章主要介紹了Java編程中的單例設(shè)計模式,在許多語言的編程過程當(dāng)中單例模式都被開發(fā)者們廣泛采用,需要的朋友可以參考下
    2015-07-07
  • 聊聊Java Double相加出現(xiàn)的怪事

    聊聊Java Double相加出現(xiàn)的怪事

    這篇文章主要介紹了Java Double相加出現(xiàn)的怪事,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • 詳解java_ 集合綜合案例:斗地主

    詳解java_ 集合綜合案例:斗地主

    這篇文章主要介紹了java_ 集合綜合案例:斗地主,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-04-04
  • springboot配置開發(fā)和測試環(huán)境并添加啟動路徑方式

    springboot配置開發(fā)和測試環(huán)境并添加啟動路徑方式

    這篇文章主要介紹了springboot配置開發(fā)和測試環(huán)境并添加啟動路徑方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • 淺談java監(jiān)聽器的作用

    淺談java監(jiān)聽器的作用

    這篇文章主要介紹了淺談java監(jiān)聽器的作用,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-09-09
  • @DS注解的使用,動態(tài)數(shù)據(jù)源,事務(wù)詳解

    @DS注解的使用,動態(tài)數(shù)據(jù)源,事務(wù)詳解

    在項目中使用多數(shù)據(jù)源時,可以借助苞米豆的dynamic-datasource-spring-boot-starter進(jìn)行配置,首先需引入相應(yīng)的jar包,并在application.yml中設(shè)置主從數(shù)據(jù)源,其中一般選擇master作為默認(rèn)數(shù)據(jù)源,在實現(xiàn)類中通過@DS注解指定數(shù)據(jù)源
    2024-09-09
  • 在日志中記錄Java異常信息的正確姿勢分享

    在日志中記錄Java異常信息的正確姿勢分享

    這篇文章主要介紹了在日志中記錄Java異常信息的正確姿勢,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • Spring七大組件是哪些以及作用

    Spring七大組件是哪些以及作用

    這篇文章主要介紹了Spring七大組件是哪些以及作用,幫助剛接觸spring的朋友更快理解,如果有說的不對的地方還請指正,需要的朋友可以參考下
    2023-03-03
  • javaWeb使用servlet搭建服務(wù)器入門

    javaWeb使用servlet搭建服務(wù)器入門

    這篇文章主要為大家詳細(xì)介紹了javaWeb使用servlet搭建服務(wù)器入門,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-11-11
  • SpringBoot萬字爆肝高級配置

    SpringBoot萬字爆肝高級配置

    SpringBoot不僅支持常規(guī)的properties配置文件,還支持yaml語言的配置文件,yaml是以數(shù)據(jù)為中心的語言,在配置數(shù)據(jù)的時候具有面向?qū)ο蟮奶卣?。application.properties是比較常見的配置文件,SpringBoot的全局配置文件的作用是對一些默認(rèn)配置的配置值進(jìn)行修改
    2022-07-07

最新評論

西充县| 望都县| 西青区| 科尔| 秦安县| 广州市| 武威市| 盖州市| 东平县| 洪江市| 香格里拉县| 南京市| 大连市| 明水县| 广德县| 漳州市| 长子县| 金沙县| 土默特左旗| 伊春市| 贵阳市| 土默特右旗| 诸暨市| 洛阳市| 盐津县| 宁陕县| 镇坪县| 朝阳市| 板桥市| 收藏| 宕昌县| 集安市| 垣曲县| 甘谷县| 南木林县| 娄底市| 乌拉特前旗| 遂溪县| 邛崃市| 百色市| 曲沃县|