<menu id="ycqsw"></menu><nav id="ycqsw"><code id="ycqsw"></code></nav>
<dd id="ycqsw"><menu id="ycqsw"></menu></dd>
  • <nav id="ycqsw"></nav>
    <menu id="ycqsw"><strong id="ycqsw"></strong></menu>
    <xmp id="ycqsw"><nav id="ycqsw"></nav>
  • java怎么升級系統框架(簡單的java程序代碼)


    1.鎖升級的4種狀態

    無鎖狀態

    偏向鎖狀態

    輕量級鎖狀態

    重量級鎖狀態

    2.整體的流程圖

    一分鐘了解java中的鎖升級,以及在對象頭中的操作

    3.詳細介紹

    一分鐘了解java中的鎖升級,以及在對象頭中的操作

    ? 偏向鎖狀態

    原因:

    大多數時候是不存在鎖競爭的,常常是一個線程多次獲得同一個鎖,因此如果每次都要競爭鎖會增大很多沒有必要付出的代價,為了降低獲取鎖的代價,才引入的偏向鎖。

    升級:

    當線程1訪問代碼塊并獲取鎖對象時,會在java對象頭和棧幀中記錄偏向的鎖的threadID,因為偏向鎖不會主動釋放鎖,因此以后線程1再次獲取鎖的時候,需要比較當前線程的threadID和Java對象頭中的threadID是否一致,如果一致(還是線程1獲取鎖對象),則無需使用CAS來加鎖、解鎖;

    如果不一致,那么需要查看Java對象頭中記錄的線程1是否存活,如果沒有存活,那么鎖對象被重置為無鎖狀態,其它線程(線程2)可以競爭將其設置為偏向鎖;

    如果存活,那么立刻查找該線程(線程1)的棧幀信息,如果還是需要繼續持有這個鎖對象,那么暫停當前線程1,撤銷偏向鎖,升級為輕量級鎖,如果線程1不再使用該鎖對象,那么將鎖對象狀態設為無鎖狀態,重新偏向新的線程。

    ? 輕量級鎖狀態

    原因:

    輕量級鎖考慮的是競爭鎖對象的線程不多,而且線程持有鎖的時間也不長的情景。因為阻塞線程需要CPU從用戶態轉到內核態,代價較大,如果剛剛阻塞不久這個鎖就被釋放了,那這個代價就有點得不償失了,因此這個時候就干脆不阻塞這個線程,讓它自旋這等待鎖釋放。

    升級:

    線程1獲取輕量級鎖時會先把鎖對象的對象頭MarkWord復制一份到線程1的棧幀中創建的用于存儲鎖記錄的空間(稱為DisplacedMarkWord),然后使用CAS把對象頭中的內容替換為線程1存儲的鎖記錄(DisplacedMarkWord)的地址;

    如果在線程1復制對象頭的同時(在線程1CAS之前),線程2也準備獲取鎖,復制了對象頭到線程2的鎖記錄空間中,但是在線程2CAS的時候,發現線程1已經把對象頭換了,線程2的CAS失敗,那么線程2就嘗試使用自旋鎖來等待線程1釋放鎖。

    但是如果自旋的時間太長也不行,因為自旋是要消耗CPU的,因此自旋的次數是有限制的,比如10次或者100次,如果自旋次數到了線程1還沒有釋放鎖,或者線程1還在執行,線程2還在自旋等待,這時又有一個線程3過來競爭這個鎖對象,那么這個時候輕量級鎖就會膨脹為重量級鎖。重量級鎖把除了擁有鎖的線程都阻塞,防止CPU空轉。

    4.對象頭布局

    對象頭:比如 hash碼,對象所屬的年代,對象鎖,鎖狀態標志,偏向鎖(線程)ID,偏向時間,數組長度(數組對象)等

    實例數據:即創建對象時,對象中成員變量,方法等

    對齊填充:對象的大小必須是8字節的整數倍

    一分鐘了解java中的鎖升級,以及在對象頭中的操作

    Mark Word

    以32位JVM中存儲內容為例:

    鎖狀態25 bit4bit1bit2bit
    鎖標志位
    是否是偏向鎖
    23bit2bit
    GC標記11
    重量級鎖指向重量級鎖Monitor的指針(依賴Mutex操作系統的互斥)10
    輕量級鎖指向線程棧中鎖記錄的指針pointer to Lock Record00
    偏向鎖線程IDEpoch對象分代年齡101
    無鎖對象的hashCode對象分代年齡001

    補充:這里的例子是32位系統,不同位數的系統對象頭略有不同

    版權聲明:本文內容由互聯網用戶自發貢獻,該文觀點僅代表作者本人。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如發現本站有涉嫌抄襲侵權/違法違規的內容, 請發送郵件至 舉報,一經查實,本站將立刻刪除。

    發表評論

    登錄后才能評論
    国产精品区一区二区免费