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

Java synchronized偏向鎖的核心原理詳解

 更新時(shí)間:2022年03月01日 16:54:45   作者:小小茶花女  
這篇文章主要為大家詳細(xì)介紹了Java synchronized偏向鎖的核心原理,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助

1. 偏向鎖的核心原理

輕量級(jí)鎖在沒(méi)有競(jìng)爭(zhēng)時(shí)(就自己這個(gè)線程),每次重入仍然需要執(zhí)行 CAS 操作。 Java 6 中引入了偏向鎖來(lái)做進(jìn)一步優(yōu)化:只有第一次使用 CAS 將線程 ID 設(shè)置到對(duì)象的 Mark Word 頭,之后發(fā)現(xiàn) 這個(gè)線程 ID 是自己的就表示沒(méi)有競(jìng)爭(zhēng),不用重新 CAS。以后只要不發(fā)生競(jìng)爭(zhēng),這個(gè)對(duì)象就歸該線程所有。

public class Main {
    static final Object obj = new Object();
    public static void main(String[] args) {
        Thread thread = new Thread(()->{
           m1();
        });
        thread.start();
    }
    public static void m1() {
        synchronized( obj ) {
            // 同步塊 A
            m2();
        }
    }
    public static void m2() {
        synchronized( obj ) {
            // 同步塊 B
            m3();
        }
    }
    public static void m3() {
        synchronized( obj ) {
            //偏向狀態(tài)
            // 同步塊 C
        }
    }
}

偏向鎖的核心原理是:如果不存在線程競(jìng)爭(zhēng)的一個(gè)線程獲得了鎖,那么鎖就進(jìn)入偏向狀態(tài),此時(shí)Mark Word的結(jié)構(gòu)變?yōu)槠蜴i結(jié)構(gòu),鎖對(duì)象的鎖標(biāo)志位(lock)被改為01,偏向標(biāo)志位(biased_lock)被改為1,然后線程的ID記錄在鎖對(duì)象的Mark Word中(使用CAS操作完成)。以后該線程獲取鎖時(shí)判斷一下線程ID和標(biāo)志位,就可以直接進(jìn)入同步塊,連CAS操作都不需要,這樣就省去了大量有關(guān)鎖申請(qǐng)的操作,從而也就提升了程序的性能。

偏向鎖的主要作用是消除無(wú)競(jìng)爭(zhēng)情況下的同步原語(yǔ),進(jìn)一步提升程序性能,所以,在沒(méi)有鎖競(jìng)爭(zhēng)的場(chǎng)合,偏向鎖有很好的優(yōu)化效果。但是,一旦有第二條線程需要競(jìng)爭(zhēng)鎖,那么偏向模式立即結(jié)束,進(jìn)入輕量級(jí)鎖的狀態(tài)。

假如在大部分情況下同步塊是沒(méi)有競(jìng)爭(zhēng)的,那么可以通過(guò)偏向來(lái)提高性能。即在無(wú)競(jìng)爭(zhēng)時(shí),之前獲得鎖的線程再次獲得鎖時(shí)會(huì)判斷偏向鎖的線程ID是否指向自己,如果是,那么該線程將不用再次獲得鎖,直接就可以進(jìn)入同步塊;如果未指向當(dāng)前線程,當(dāng)前線程就會(huì)采用CAS操作將Mark Word中的線程ID設(shè)置為當(dāng)前線程ID,如果CAS操作成功,那么獲取偏向鎖成功,執(zhí)行同步代碼塊,如果CAS操作失敗,那么表示有競(jìng)爭(zhēng),搶鎖線程被掛起,撤銷占鎖線程的偏向鎖,然后將偏向鎖膨脹為輕量級(jí)鎖。

在這里插入圖片描述

偏向鎖的加鎖過(guò)程為:新線程只需要判斷內(nèi)置鎖對(duì)象的Mark Word中的線程ID是不是自己的ID,如果是就直接使用這個(gè)鎖,而不使用CAS交換;如果不是,比如在第一次獲得此鎖時(shí)內(nèi)置鎖的線程ID為空,就使用CAS交換,新線程將自己的線程ID交換到內(nèi)置鎖的Mark Word中,如果交換成功,就加鎖成功。

每執(zhí)行一輪搶占,JVM內(nèi)部都會(huì)比較內(nèi)置鎖的偏向線程ID與當(dāng)前線程ID,如果匹配,就表明當(dāng)前線程已經(jīng)獲得了偏向鎖,當(dāng)前線程可以快速進(jìn)入臨界區(qū)。所以,偏向鎖的效率是非常高的??傊?,偏向鎖是針對(duì)一個(gè)線程而言的,線程獲得鎖之后就不會(huì)再有解鎖等操作了,這樣可以省略很多開(kāi)銷。

偏向鎖的缺點(diǎn):如果鎖對(duì)象時(shí)常被多個(gè)線程競(jìng)爭(zhēng),偏向鎖就是多余的,并且其撤銷的過(guò)程會(huì)帶來(lái)一些性能開(kāi)銷。

2. 偏向鎖的撤銷

假如有多個(gè)線程來(lái)競(jìng)爭(zhēng)偏向鎖,此對(duì)象鎖已經(jīng)有所偏向,其他的線程發(fā)現(xiàn)偏向鎖并不是偏向自己,就說(shuō)明存在了競(jìng)爭(zhēng),嘗試撤銷偏向鎖(很可能引入安全點(diǎn)),然后膨脹到輕量級(jí)鎖。

偏向鎖撤銷的開(kāi)銷花費(fèi)還是挺大的,其大概過(guò)程如下:

(1) 在一個(gè)安全點(diǎn)停止擁有鎖的線程。

(2) 遍歷線程的棧幀,檢查是否存在鎖記錄。如果存在鎖記錄,就需要清空鎖記錄,使其變成無(wú)鎖狀態(tài),并修復(fù)鎖記錄指向的Mark Word,清除其線程ID。

(3) 將當(dāng)前鎖升級(jí)成輕量級(jí)鎖。

(4) 喚醒當(dāng)前線程。

所以,如果某些臨界區(qū)存在兩個(gè)及兩個(gè)以上的線程競(jìng)爭(zhēng),那么偏向鎖反而會(huì)降低性能。在這種情況下,可以在啟動(dòng)JVM時(shí)就把偏向鎖的默認(rèn)功能關(guān)閉。

撤銷偏向鎖的條件:

(1) 多個(gè)線程競(jìng)爭(zhēng)偏向鎖。

(2) 調(diào)用偏向鎖對(duì)象的hashcode()方法或者System.identityHashCode()方法計(jì)算對(duì)象的HashCode之后,將哈希碼放置到Mark Word中,內(nèi)置鎖變成無(wú)鎖狀態(tài),偏向鎖將被撤銷。

3. 偏向鎖的膨脹

如果偏向鎖被占據(jù),一旦有第二個(gè)線程爭(zhēng)搶這個(gè)對(duì)象,因?yàn)槠蜴i不會(huì)主動(dòng)釋放,所以第二個(gè)線程可以看到內(nèi)置鎖偏向狀態(tài),這時(shí)表明在這個(gè)對(duì)象鎖上已經(jīng)存在競(jìng)爭(zhēng)了。JVM檢查原來(lái)持有該對(duì)象鎖的占有線程是否依然存活,如果掛了,就可以將對(duì)象變?yōu)闊o(wú)鎖狀態(tài),然后進(jìn)行重新偏向,偏向?yàn)閾屾i線程。

如果JVM檢查到原來(lái)的線程依然存活,就進(jìn)一步檢查占有線程的調(diào)用堆棧是否通過(guò)鎖記錄持有偏向鎖。如果存在鎖記錄,就表明原來(lái)的線程還在使用偏向鎖,發(fā)生鎖競(jìng)爭(zhēng),撤銷原來(lái)的偏向鎖,將偏向鎖膨脹(INFLATING)為輕量級(jí)鎖。

4. 偏向鎖的好處

經(jīng)驗(yàn)表明,其實(shí)大部分情況下進(jìn)入一個(gè)同步代碼塊的線程都是同一個(gè)線程。這也是JDK會(huì)引入偏向鎖的原因。所以,總體來(lái)說(shuō),使用偏向鎖帶來(lái)的好處還是大于偏向鎖撤銷和膨脹所帶來(lái)的代價(jià)。

總結(jié)

本篇文章就到這里了,希望能夠給你帶來(lái)幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容! 

相關(guān)文章

  • java跟蹤執(zhí)行的sql語(yǔ)句示例分享

    java跟蹤執(zhí)行的sql語(yǔ)句示例分享

    這篇文章主要介紹了java跟蹤執(zhí)行的sql語(yǔ)句示例分享,需要的朋友可以參考下
    2014-03-03
  • Java 多用戶登錄限制的實(shí)現(xiàn)方法

    Java 多用戶登錄限制的實(shí)現(xiàn)方法

    最近沒(méi)有事情做,閑的發(fā)呆,于是寫(xiě)個(gè)東東練練手。這篇文章主要介紹了Java 多用戶登錄限制的實(shí)現(xiàn)方法的相關(guān)資料,需要的朋友可以參考下
    2016-11-11
  • SpringBoot如何集成i18n(多語(yǔ)言)

    SpringBoot如何集成i18n(多語(yǔ)言)

    這篇文章主要介紹了SpringBoot如何集成i18n(多語(yǔ)言)問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-04-04
  • JVM虛擬機(jī)的類加載機(jī)制詳解

    JVM虛擬機(jī)的類加載機(jī)制詳解

    這篇文章主要介紹了JVM虛擬機(jī)的類加載機(jī)制詳解,類是在運(yùn)行期間第一次使用時(shí)動(dòng)態(tài)加載的,而不是一次性加載所有類,因?yàn)槿绻淮涡约虞d,那么會(huì)占用很多的內(nèi)存,需要的朋友可以參考下
    2023-12-12
  • MyBatis分頁(yè)查詢返回list的時(shí)候出現(xiàn)null的問(wèn)題

    MyBatis分頁(yè)查詢返回list的時(shí)候出現(xiàn)null的問(wèn)題

    這篇文章主要介紹了MyBatis分頁(yè)查詢返回list的時(shí)候出現(xiàn)null的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-07-07
  • SpringBoot + Mybatis增刪改查實(shí)戰(zhàn)記錄

    SpringBoot + Mybatis增刪改查實(shí)戰(zhàn)記錄

    這篇文章主要給大家介紹了關(guān)于SpringBoot + Mybatis增刪改查的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-05-05
  • Java多線程run方法中直接調(diào)用service業(yè)務(wù)類應(yīng)注意的問(wèn)題及解決

    Java多線程run方法中直接調(diào)用service業(yè)務(wù)類應(yīng)注意的問(wèn)題及解決

    這篇文章主要介紹了Java多線程run方法中直接調(diào)用service業(yè)務(wù)類應(yīng)注意的問(wèn)題及解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-06-06
  • springboot自定義日志注解的實(shí)現(xiàn)

    springboot自定義日志注解的實(shí)現(xiàn)

    本文主要介紹了springboot自定義日志注解的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • Windows下Java調(diào)用OCR進(jìn)行圖片識(shí)別

    Windows下Java調(diào)用OCR進(jìn)行圖片識(shí)別

    這篇文章主要為大家詳細(xì)介紹了Windows下Java調(diào)用OCR進(jìn)行圖片識(shí)別,通過(guò)Tesseract-OCR對(duì)圖片進(jìn)行識(shí)別,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-12-12
  • MyBatis中PageHelper不生效的解決方案

    MyBatis中PageHelper不生效的解決方案

    這篇文章主要介紹了MyBatis中PageHelper不生效的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-06-06

最新評(píng)論

武陟县| 任丘市| 邛崃市| 江川县| 馆陶县| 黎平县| 霍林郭勒市| 夏河县| 漳平市| 千阳县| 清流县| 永州市| 浪卡子县| 惠东县| 吉林市| 涡阳县| 台中县| 安图县| 仪征市| 逊克县| 浙江省| 即墨市| 广东省| 顺昌县| 沭阳县| 永宁县| 白朗县| 广水市| 二连浩特市| 汤阴县| 繁昌县| 洛隆县| 集贤县| 中西区| 屏东县| 黄浦区| 会东县| 建德市| 新郑市| 鹤庆县| 两当县|