二維碼
        企資網(wǎng)

        掃一掃關(guān)注

        當(dāng)前位置: 首頁(yè) » 企業(yè)資訊 » 行業(yè) » 正文

        Synchronized_中的_4_個(gè)優(yōu)化,

        放大字體  縮小字體 發(fā)布日期:2021-09-10 01:05:41    作者:企資小編    瀏覽次數(shù):48
        導(dǎo)讀

        synchronized 在 JDK 1.5 時(shí)性能是比較低的,然而在后續(xù)的版本中經(jīng)過(guò)各種優(yōu)化迭代,它的性能也得到了前所未有的提升,之前說(shuō)到過(guò)鎖膨脹對(duì) synchronized 性能的提升,然而它也只是“眾多” synchronized 性能優(yōu)化方案

        synchronized 在 JDK 1.5 時(shí)性能是比較低的,然而在后續(xù)的版本中經(jīng)過(guò)各種優(yōu)化迭代,它的性能也得到了前所未有的提升,之前說(shuō)到過(guò)鎖膨脹對(duì) synchronized 性能的提升,然而它也只是“眾多” synchronized 性能優(yōu)化方案中的一種,那么我們本文就來(lái)盤點(diǎn)一下 synchronized 的核心優(yōu)化方案。

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

        1. 鎖膨脹
        2. 鎖消除
        3. 鎖粗化
        4. 自適應(yīng)自旋鎖

        1.鎖膨脹

        我們先來(lái)回顧一下鎖膨脹對(duì) synchronized 性能的影響,所謂的鎖膨脹是指 synchronized 從無(wú)鎖升級(jí)到偏向鎖,再到輕量級(jí)鎖,最后到重量級(jí)鎖的過(guò)程,它叫做鎖膨脹也叫做鎖升級(jí)。

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

        2.鎖消除

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

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

        鎖消除的依據(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)過(guò)編譯之后的字節(jié)碼如下:

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

        3.鎖粗化

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

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

        沒(méi)錯(cuò),鎖細(xì)化的觀點(diǎn)在大多數(shù)情況下都是成立了,但是一系列連續(xù)加鎖和解鎖的操作,也會(huì)導(dǎo)致不必要的性能開(kāi)銷,從而影響程序的執(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)的外層加一把鎖,那么對(duì)于同一個(gè)對(duì)象操作這段代碼的性能就會(huì)提高很多,如下偽代碼所示:

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

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

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

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

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

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

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

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

        總結(jié)

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


        作者:Java中文社群
        原文鏈接:juejin/post/6994443415911923719

         
        (文/企資小編)
        免責(zé)聲明
        本文僅代表作發(fā)布者:企資小編個(gè)人觀點(diǎn),本站未對(duì)其內(nèi)容進(jìn)行核實(shí),請(qǐng)讀者僅做參考,如若文中涉及有違公德、觸犯法律的內(nèi)容,一經(jīng)發(fā)現(xiàn),立即刪除,需自行承擔(dān)相應(yīng)責(zé)任。涉及到版權(quán)或其他問(wèn)題,請(qǐng)及時(shí)聯(lián)系我們刪除處理郵件:weilaitui@qq.com。
         

        Copyright ? 2016 - 2025 - 企資網(wǎng) 48903.COM All Rights Reserved 粵公網(wǎng)安備 44030702000589號(hào)

        粵ICP備16078936號(hào)

        微信

        關(guān)注
        微信

        微信二維碼

        WAP二維碼

        客服

        聯(lián)系
        客服

        聯(lián)系客服:

        在線QQ: 303377504

        客服電話: 020-82301567

        E_mail郵箱: weilaitui@qq.com

        微信公眾號(hào): weishitui

        客服001 客服002 客服003

        工作時(shí)間:

        周一至周五: 09:00 - 18:00

        反饋

        用戶
        反饋

        亚洲AV区无码字幕中文色| 无码精品人妻一区二区三区免费看| 精品无码一区二区三区爱欲九九| 亚洲欧美日韩中文久久| 无码aⅴ精品一区二区三区浪潮| 久久国产高清字幕中文| 日韩乱码人妻无码中文视频| 亚洲av无码精品网站| 亚洲中文字幕伊人久久无码| 久久中文字幕人妻熟av女| 国产亚洲3p无码一区二区| 中文字幕无码人妻AAA片| 最近2019年中文字幕一页| 亚洲区日韩区无码区| 久久久久亚洲精品无码蜜桃| 久久无码专区国产精品发布| 中文字幕高清有码在线中字| 天堂在线最新版资源www中文| 97碰碰碰人妻视频无码| 无码视频在线观看| 免费无码一区二区三区蜜桃| 一本久中文视频播放| 无码中文字幕乱在线观看 | 久久中文字幕一区二区| 少妇无码?V无码专区在线观看| 无码国产精品一区二区免费16 | 无码av高潮喷水无码专区线| 中文字幕国产在线| 久久亚洲春色中文字幕久久久| 日韩成人无码中文字幕| 无码专区国产无套粉嫩白浆内射| 日韩一区二区三区无码影院| 无码H肉动漫在线观看| 无码人妻丰满熟妇区五十路百度| 亚洲精品无码乱码成人| 国产色无码精品视频免费| 中文字幕国产第一页首页| 中文字幕人成乱码在线观看| 中文字幕日韩第十页在线观看 | 无码人妻一区二区三区免费n鬼沢| 亚洲成AV人片在线播放无码|