欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

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

1. 偏向鎖的核心原理

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

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
        }
    }
}

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

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

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

在這里插入圖片描述

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

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

偏向鎖的缺點:如果鎖對象時常被多個線程競爭,偏向鎖就是多余的,并且其撤銷的過程會帶來一些性能開銷。

2. 偏向鎖的撤銷

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

偏向鎖撤銷的開銷花費還是挺大的,其大概過程如下:

(1) 在一個安全點停止擁有鎖的線程。

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

(3) 將當前鎖升級成輕量級鎖。

(4) 喚醒當前線程。

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

撤銷偏向鎖的條件:

(1) 多個線程競爭偏向鎖。

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

3. 偏向鎖的膨脹

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

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

4. 偏向鎖的好處

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

總結(jié)

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

相關(guān)文章

  • Java實現(xiàn)彈窗效果的基本操作(2)

    Java實現(xiàn)彈窗效果的基本操作(2)

    這篇文章主要為大家詳細介紹了Java實現(xiàn)彈窗效果的基本操作第二篇,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-07-07
  • SpringCloud Alibaba框架介紹

    SpringCloud Alibaba框架介紹

    spring cloud是一個基于springboot實現(xiàn)的微服務(wù)架構(gòu)開發(fā)工具,目前主流的SpringCloud分為SpringCloud Netflix和阿里云開源的SpringCloud Alibaba兩個系列,本文主要介紹SpringCloud Alibaba框架,感興趣的朋友可以參考一下
    2023-04-04
  • java實現(xiàn)液晶數(shù)字字體顯示當前時間

    java實現(xiàn)液晶數(shù)字字體顯示當前時間

    這篇文章主要為大家詳細介紹了java實現(xiàn)液晶數(shù)字字體顯示當前時間,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-12-12
  • 淺談Redis持久化的幾種方式

    淺談Redis持久化的幾種方式

    這篇文章主要介紹了淺談Redis持久化的幾種方式,前面說到了Redis持久化的 實現(xiàn)方式主要分為了:快照持久化(RDB)、寫日志持久化(AOF)
    ,其中快照持久化方式也就是RDB ,需要的朋友可以參考下
    2023-08-08
  • Assert.assertNotNull()斷言是否是空問題

    Assert.assertNotNull()斷言是否是空問題

    這篇文章主要介紹了Assert.assertNotNull()斷言是否是空問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-10-10
  • Mapper.xml中查詢返回帶有List屬性的實體類結(jié)果問題

    Mapper.xml中查詢返回帶有List屬性的實體類結(jié)果問題

    這篇文章主要介紹了Mapper.xml中查詢返回帶有List屬性的實體類結(jié)果問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-06-06
  • java實現(xiàn)貪吃蛇極速版

    java實現(xiàn)貪吃蛇極速版

    這篇文章主要為大家分享了java貪吃蛇極速版,貪吃蛇經(jīng)典手機游戲,既簡單又耐玩,本文用java來實現(xiàn)下貪吃蛇小游戲,感興趣的小伙伴可以參考下
    2015-12-12
  • Java實現(xiàn)動態(tài)驗證碼生成

    Java實現(xiàn)動態(tài)驗證碼生成

    這篇文章主要為大家詳細介紹了Java實現(xiàn)動態(tài)驗證碼生成,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-04-04
  • java中的Struts2攔截器詳解

    java中的Struts2攔截器詳解

    本篇文章主要介紹了java中的Struts2攔截器淺解,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-03-03
  • SpringBoot雪花算法主鍵ID傳到前端后精度丟失問題的解決

    SpringBoot雪花算法主鍵ID傳到前端后精度丟失問題的解決

    本文主要介紹了SpringBoot雪花算法主鍵ID傳到前端后精度丟失問題的解決,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-08-08

最新評論