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

Java中synchronized鎖的深入理解

 更新時(shí)間:2023年05月29日 08:35:02   作者:舒一笑  
這篇本文主要對(duì)Java中synchronized鎖進(jìn)行深入理解,文中通過(guò)synchronized的優(yōu)化,synchronized的實(shí)現(xiàn)原理及synchronized的升級(jí)過(guò)程來(lái)介紹Java中synchronized鎖,感興趣的同學(xué)可以跟著小編一起來(lái)學(xué)習(xí)

使用范圍

  • synchronized使用上用于同步方法或者同步代碼塊
  • 在鎖實(shí)現(xiàn)上是基于對(duì)象去實(shí)現(xiàn)
  • 使用中用于對(duì)static修飾的便是class類(lèi)鎖
  • 使用中用于對(duì)非static修飾的便是當(dāng)前對(duì)象鎖

synchronized的優(yōu)化

  • 在jdk1.6中對(duì)synchronized做了相關(guān)的優(yōu)化

鎖消除

  • 在synchronized修飾的代碼塊中,要是不涉及操作臨界資源的情況,即便你寫(xiě)了synchronized修飾,也不會(huì)出發(fā)鎖機(jī)制

鎖膨脹

  • 在一個(gè)循環(huán)中頻繁的出現(xiàn)鎖資源的獲取與釋放操作,會(huì)帶來(lái)資源的消耗,于是便會(huì)將鎖的范圍擴(kuò)大到循環(huán)的外邊,避免頻繁的競(jìng)爭(zhēng)和獲取鎖資源而導(dǎo)致的資源消耗
  public void method(){
        for (int i = 0; i < Integer.MAX_VALUE; i++) {
            synchronized ("") {
                // 業(yè)務(wù)代碼
            }
        }
    }

鎖升級(jí)

  • ReentrantLock中是基于樂(lè)觀鎖的CAS獲取線(xiàn)程資源。資源拿不到的情況下才會(huì)掛起線(xiàn)程。synchronized在jdk1.6之間完全獲取不到鎖的情況下立即掛起線(xiàn)程,但是在1.6之后進(jìn)行了鎖的升級(jí)與優(yōu)化。
  • 無(wú)鎖、匿名偏向:當(dāng)前對(duì)象沒(méi)有作為鎖的存在
  • 偏向鎖:當(dāng)前鎖資源,只有一個(gè)線(xiàn)程頻繁的獲取和釋放鎖,那么只有該線(xiàn)程獲取鎖是判斷是否是同一個(gè)線(xiàn)程,如果是線(xiàn)程資源拿走。如果線(xiàn)程不是當(dāng)前自己的線(xiàn)程,則采用基于CAS的方式,嘗試將偏向鎖指向當(dāng)前線(xiàn)程。如果獲取不到則觸發(fā)鎖升級(jí)為輕量級(jí)鎖,也就意味著發(fā)生了鎖競(jìng)爭(zhēng)的情況。
  • 輕量級(jí)鎖:使用自旋鎖的方式頻繁的采用CAS的方式獲取鎖資源。這里采用的自適應(yīng)自旋鎖(JVM更具上次的自旋結(jié)果來(lái)進(jìn)行判斷本次的自旋時(shí)間長(zhǎng)短)。如果成功獲取鎖資源,資源取走。如果獲取鎖資源失敗,鎖升級(jí)。
  • 重量級(jí)鎖:最為傳統(tǒng)的synchronized實(shí)現(xiàn)方式。拿不到鎖資源之間掛起線(xiàn)程,然后進(jìn)行用戶(hù)態(tài)和內(nèi)核態(tài)的不斷切換。。。

synchronized鎖的實(shí)現(xiàn)原理

  • synchronized鎖是基于對(duì)象來(lái)進(jìn)行實(shí)現(xiàn)的

  • 關(guān)于MarkWord的內(nèi)容展開(kāi)示意圖

  • 從圖中可以看出通過(guò)鎖的標(biāo)志位來(lái)進(jìn)行區(qū)分鎖的不同狀態(tài)

synchronized鎖升級(jí)的過(guò)程演示

  • 使用之前需要導(dǎo)入一個(gè)依賴(lài)
<dependency>
            <groupId>org.openjdk.jol</groupId>
            <artifactId>jol-core</artifactId>
            <version>0.9</version>
        </dependency>

  • 鎖在默認(rèn)情況下,開(kāi)啟了偏向鎖的延遲
  • 原因是因?yàn)樵谄蜴i升級(jí)為輕量級(jí)鎖的時(shí)候會(huì)涉及到偏向鎖的撤銷(xiāo),需要等到一個(gè)安全點(diǎn)(STW),才能完成對(duì)偏向鎖的撤銷(xiāo),所以在并發(fā)的情況下就可以選擇不開(kāi)啟偏向鎖,或者設(shè)置偏向鎖延遲開(kāi)啟
  • 在JVM啟動(dòng)時(shí)會(huì)大量加載.class文件到內(nèi)存,該操作會(huì)涉及synchronized使用,為了避免出現(xiàn)偏向鎖撤銷(xiāo)的操作。在啟動(dòng)初期,有一個(gè)延遲5s開(kāi)啟偏向鎖的操作。
  • 要是正常開(kāi)啟偏向鎖,那么就不會(huì)出現(xiàn)無(wú)鎖的狀態(tài),而是直接進(jìn)入匿名偏向鎖

  • 變成了偏向鎖

/**
 * @author
 * @date 2023/5/28
 */
public class Test15 {
    public static void main(String[] args) throws InterruptedException {
        Thread.sleep(5000);
        Object o = new Object();
        System.out.println(ClassLayout.parseInstance(o).toPrintable());
		//thread 線(xiàn)程偏向鎖
        Thread thread = new Thread(()->{
            synchronized (o){
                System.out.println("thread線(xiàn)程 :"+ClassLayout.parseInstance(o).toPrintable());
            }
        });
        thread.start();
        // 輕量級(jí)鎖 -> 重量級(jí)鎖
        synchronized (o){
            System.out.println("main線(xiàn)程 :"+ClassLayout.parseInstance(o).toPrintable());
        }
    }
}

鎖轉(zhuǎn)換狀態(tài)示意圖

LockRecord和ObjectMonitor存儲(chǔ)的內(nèi)容示意圖

以上就是Java中synchronized鎖的深入理解的詳細(xì)內(nèi)容,更多關(guān)于Java synchronized鎖的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評(píng)論