国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

并發(fā)編程11:Synchronized與鎖升級(jí)

這篇具有很好參考價(jià)值的文章主要介紹了并發(fā)編程11:Synchronized與鎖升級(jí)。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

11.1 面試題

  • 談?wù)勀銓?duì)Synchronized的理解
  • Sychronized的鎖升級(jí)你聊聊
  • Synchronized實(shí)現(xiàn)原理,monitor對(duì)象什么時(shí)候生成的?知道m(xù)onitor的monitorenter和monitorexit這兩個(gè)是怎么保證同步的嘛?或者說這兩個(gè)操作計(jì)算機(jī)底層是如何執(zhí)行的
  • 偏向鎖和輕量級(jí)鎖有什么區(qū)別

11.2 Synchronized的性能變化

  • Java5以前,只有Synchronized,這個(gè)是操作系統(tǒng)級(jí)別的重量級(jí)操作

    • 重量級(jí)鎖,假如鎖的競(jìng)爭(zhēng)比較激烈的話,性能下降
    • Java 5之前 用戶態(tài)和內(nèi)核態(tài)之間的轉(zhuǎn)換
      并發(fā)編程11:Synchronized與鎖升級(jí)
  • Java6 之后為了減少獲得鎖和釋放鎖所帶來的性能消耗,引入了輕量級(jí)鎖和偏向鎖

11.3 Synchronized鎖種類及升級(jí)步驟

11.3.1 多線程訪問情況

  • 只有一個(gè)線程來訪問,有且唯一Only One
  • 有兩個(gè)線程(2個(gè)線程交替訪問)
  • 競(jìng)爭(zhēng)激烈,更多線程來訪問

11.3.2 升級(jí)流程

  • Synchronized用的鎖是存在Java對(duì)象頭里的MarkWord中,鎖升級(jí)功能主要依賴MarkWord中鎖標(biāo)志位和釋放偏向鎖標(biāo)志位
    并發(fā)編程11:Synchronized與鎖升級(jí)

  • 鎖指向,請(qǐng)牢記

    • 偏向鎖:MarkWord存儲(chǔ)的是偏向的線程ID
    • 輕量鎖:MarkWord存儲(chǔ)的是指向線程棧中Lock Record的指針
    • 重量鎖:MarkWord存儲(chǔ)的是指向堆中的monitor對(duì)象(系統(tǒng)互斥量指針)

11.3.3 無鎖

并發(fā)編程11:Synchronized與鎖升級(jí)

11.3.4 偏鎖

偏向鎖:?jiǎn)尉€程競(jìng)爭(zhēng),當(dāng)線程A第一次競(jìng)爭(zhēng)到鎖時(shí),通過修改MarkWord中的偏向線程ID、偏向模式。如果不存在其他線程競(jìng)爭(zhēng),那么持有偏向鎖的線程將永遠(yuǎn)不需要進(jìn)行同步。
主要作用:

  • 當(dāng)一段同步代碼一直被同一個(gè)線程多次訪問,由于只有一個(gè)線程那么該線程在后續(xù)訪問時(shí)便會(huì)自動(dòng)獲得鎖
  • 同一個(gè)老顧客來訪,直接老規(guī)矩行方便
    結(jié)論:
  • HotSpot的作者經(jīng)過研究發(fā)現(xiàn),大多數(shù)情況下:在多線程情況下,鎖不僅不存在多線程競(jìng)爭(zhēng),還存在由同一個(gè)線程多次獲得的情況,偏向鎖就是在這種情況下出現(xiàn)的,它的出現(xiàn)是為了解決只有一個(gè)線程執(zhí)行同步時(shí)提高性能
  • 偏向鎖會(huì)偏向于第一個(gè)訪問鎖的線程,如果在接下來的運(yùn)行過程中,該鎖沒有被其他線程訪問,則持有偏向鎖的線程將永遠(yuǎn)不需要出發(fā)同步。也即偏向鎖在資源在沒有競(jìng)爭(zhēng)情況下消除了同步語句,懶得連CAS操作都不做了,直接提高程序性能。
    理論落地:
    并發(fā)編程11:Synchronized與鎖升級(jí)

技術(shù)實(shí)現(xiàn):
并發(fā)編程11:Synchronized與鎖升級(jí)

偏向鎖JVM命令:
并發(fā)編程11:Synchronized與鎖升級(jí)

案例演示:

  • 偏向鎖默認(rèn)情況演示—只有一個(gè)線程
public class SynchronizedUpDemo {

    public static void main(String[] args) {
        /**
         * 這里偏向鎖在JDK6以上默認(rèn)開啟,開啟后程序啟動(dòng)幾秒后才會(huì)被激活,可以通過JVM參數(shù)來關(guān)閉延遲 -XX:BiasedLockingStartupDelay=0
         */
//        try { TimeUnit.SECONDS.sleep(5); } catch (InterruptedException e) { e.printStackTrace(); }
        Object o = new Object();
        synchronized (o) {
            System.out.println(ClassLayout.parseInstance(o).toPrintable());
        }
    }
}

并發(fā)編程11:Synchronized與鎖升級(jí)

偏向鎖的撤銷:

  • 當(dāng)有另外一個(gè)線程逐步來競(jìng)爭(zhēng)鎖的時(shí)候,就不能再使用偏向鎖了,要升級(jí)為輕量級(jí)鎖,使用的是等到競(jìng)爭(zhēng)出現(xiàn)才釋放鎖的機(jī)制
  • 競(jìng)爭(zhēng)線程嘗試CAS更新對(duì)象頭失敗,會(huì)等到全局安全點(diǎn)此時(shí)不會(huì)執(zhí)行任何代碼)撤銷偏向鎖,同時(shí)檢查持有偏向鎖的線程是否還在執(zhí)行:
    • 第一個(gè)線程正在執(zhí)行Synchronized方法(處于同步塊),它還沒有執(zhí)行完,其他線程來搶奪,該偏向鎖會(huì)被取消掉并出現(xiàn)鎖升級(jí),此時(shí)輕量級(jí)鎖由原來持有偏向鎖的線程持有,繼續(xù)執(zhí)行同步代碼塊,而正在競(jìng)爭(zhēng)的線程會(huì)自動(dòng)進(jìn)入自旋等待獲得該輕量級(jí)鎖
    • 第一個(gè)線程執(zhí)行完Synchronized(退出同步塊),則將對(duì)象頭設(shè)置為無所狀態(tài)并撤銷偏向鎖,重新偏向。
      并發(fā)編程11:Synchronized與鎖升級(jí)

題外話:Java15以后逐步廢棄偏向鎖,需要手動(dòng)開啟------->維護(hù)成本高

11.3.5 輕鎖

概念:多線程競(jìng)爭(zhēng),但是任意時(shí)候最多只有一個(gè)線程競(jìng)爭(zhēng),即不存在鎖競(jìng)爭(zhēng)太激烈的情況,也就沒有線程阻塞。
主要作用:有線程來參與鎖的競(jìng)爭(zhēng),但是獲取鎖的沖突時(shí)間極短---------->本質(zhì)是自旋鎖CAS
并發(fā)編程11:Synchronized與鎖升級(jí)

輕量鎖的獲?。?br>并發(fā)編程11:Synchronized與鎖升級(jí)
并發(fā)編程11:Synchronized與鎖升級(jí)

案例演示:
并發(fā)編程11:Synchronized與鎖升級(jí)

自旋一定程度和次數(shù)(Java8 之后是自適應(yīng)自旋鎖------意味著自旋的次數(shù)不是固定不變的):

  • 線程如果自旋成功了,那下次自旋的最大次數(shù)會(huì)增加,因?yàn)镴VM認(rèn)為既然上次成功了,那么這一次也大概率會(huì)成功
  • 如果很少會(huì)自選成功,那么下次會(huì)減少自旋的次數(shù)甚至不自旋,避免CPU空轉(zhuǎn)

輕量鎖和偏向鎖的區(qū)別:

  • 爭(zhēng)奪輕量鎖失敗時(shí),自旋嘗試搶占鎖
  • 輕量級(jí)鎖每次退出同步塊都需要釋放鎖,而偏向鎖是在競(jìng)爭(zhēng)發(fā)生時(shí)才釋放鎖

11.3.6 重鎖

有大量線程參與鎖的競(jìng)爭(zhēng),沖突性很高
并發(fā)編程11:Synchronized與鎖升級(jí)
并發(fā)編程11:Synchronized與鎖升級(jí)

11.3.7 小總結(jié)

  • 鎖升級(jí)的過程
    并發(fā)編程11:Synchronized與鎖升級(jí)

  • 鎖升級(jí)后,hashcode去哪兒了?
    并發(fā)編程11:Synchronized與鎖升級(jí)
    并發(fā)編程11:Synchronized與鎖升級(jí)

  • 各種鎖優(yōu)缺點(diǎn)、synchronized鎖升級(jí)和實(shí)現(xiàn)原理
    并發(fā)編程11:Synchronized與鎖升級(jí)

11.4 JIT編譯器對(duì)鎖的優(yōu)化

11.4.1 JIT

Just In Time Compiler 即時(shí)編譯器

11.4.2 鎖消除

/**
 * 鎖消除
 * 從JIT角度看想相當(dāng)于無視他,synchronized(o)不存在了
 * 這個(gè)鎖對(duì)象并沒有被共用擴(kuò)散到其他線程使用
 * 極端的說就是根本沒有加鎖對(duì)象的底層機(jī)器碼,消除了鎖的使用
 */

public class LockClearUpDemo {
    static Object object = new Object();

    public void m1() {
        //鎖消除問題,JIT會(huì)無視它,synchronized(o)每次new出來的,都不存在了,非正常的
        Object o = new Object();
        synchronized (o) {
            System.out.println("-----------hello LockClearUpDemo" + "\t" + o.hashCode() + "\t" + object.hashCode());
        }
    }

    public static void main(String[] args) {
        LockClearUpDemo lockClearUpDemo = new LockClearUpDemo();
        for (int i = 0; i < 10; i++) {
            new Thread(() -> {
                lockClearUpDemo.m1();
            }, String.valueOf(i)).start();
        }
    }
}
/**
 * -----------hello LockClearUpDemo	229465744	57319765
 * -----------hello LockClearUpDemo	219013680	57319765
 * -----------hello LockClearUpDemo	1109337020	57319765
 * -----------hello LockClearUpDemo	94808467	57319765
 * -----------hello LockClearUpDemo	973369600	57319765
 * -----------hello LockClearUpDemo	64667370	57319765
 * -----------hello LockClearUpDemo	1201983305	57319765
 * -----------hello LockClearUpDemo	573110659	57319765
 * -----------hello LockClearUpDemo	1863380256	57319765
 * -----------hello LockClearUpDemo	1119787251	57319765
 */

11.4.3 鎖粗化

/**
 * 鎖粗化
 * 假如方法中首尾相接,前后相鄰的都是同一個(gè)鎖對(duì)象,那JIT編譯器會(huì)把這幾個(gè)synchronized塊合并為一個(gè)大塊
 * 加粗加大范圍,一次申請(qǐng)鎖使用即可,避免次次的申請(qǐng)和釋放鎖,提高了性能
 */
public class LockBigDemo {
    static Object objectLock = new Object();

    public static void main(String[] args) {
        new Thread(() -> {
            synchronized (objectLock) {
                System.out.println("111111111111");
            }
            synchronized (objectLock) {
                System.out.println("222222222222");
            }
            synchronized (objectLock) {
                System.out.println("333333333333");
            }
            synchronized (objectLock) {
                System.out.println("444444444444");
            }
            //底層JIT的鎖粗化優(yōu)化
            synchronized (objectLock) {
                System.out.println("111111111111");
                System.out.println("222222222222");
                System.out.println("333333333333");
                System.out.println("444444444444");
            }
        }, "t1").start();
    }
}

11.5 小總結(jié)

沒有鎖:自由自在
偏向鎖:一個(gè)線程
輕量鎖:兩個(gè)線程,CAS
重量鎖:多個(gè)線程,阻塞文章來源地址http://www.zghlxwxcb.cn/news/detail-444396.html

到了這里,關(guān)于并發(fā)編程11:Synchronized與鎖升級(jí)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包