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

Java 中 synchronized 的使用方式和鎖升級(jí)

 更新時(shí)間:2025年03月05日 14:26:52   作者:謝家小布柔  
Java中的synchronized關(guān)鍵字用于實(shí)現(xiàn)線程同步,保證同一時(shí)刻只有一個(gè)線程可以訪問(wèn)被同步的代碼塊或方法,JVM引入了鎖升級(jí)機(jī)制,從無(wú)鎖狀態(tài)開(kāi)始,根據(jù)競(jìng)爭(zhēng)情況逐步升級(jí)為偏向鎖、輕量級(jí)鎖和重量級(jí)鎖,以提高性能,感興趣的朋友一起看看吧

在 Java 并發(fā)編程中,synchronized是一個(gè)非常重要的關(guān)鍵字,用于實(shí)現(xiàn)線程同步,保證在同一時(shí)刻只有一個(gè)線程可以訪問(wèn)被同步的代碼塊或方法,從而避免多線程帶來(lái)的數(shù)據(jù)不一致等問(wèn)題。同時(shí),Java 虛擬機(jī)(JVM)為了提高ynchronized的性能,引入了鎖升級(jí)機(jī)制。下面我們就來(lái)詳細(xì)介紹ynchronized的使用和鎖升級(jí)過(guò)程。

一、synchronized 的使用方式

(一)修飾普通方法

當(dāng)synchronized修飾一個(gè)普通方法時(shí),鎖對(duì)象是當(dāng)前對(duì)象(this)。也就是說(shuō),當(dāng)一個(gè)線程進(jìn)入該方法時(shí),會(huì)自動(dòng)獲取當(dāng)前對(duì)象的鎖,其他線程想要進(jìn)入該方法,必須等待當(dāng)前線程釋放鎖。例如:

public class SynchronizedExample {
    public synchronized void synchronizedMethod() {
        // 線程同步的代碼邏輯
        System.out.println("線程 " + Thread.currentThread().getName() + " 進(jìn)入同步方法");
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("線程 " + Thread.currentThread().getName() + " 退出同步方法");
    }
}

在上述代碼中,synchronizedMethod是一個(gè)同步方法,多個(gè)線程同時(shí)調(diào)用該方法時(shí),會(huì)依次排隊(duì)執(zhí)行,保證了方法內(nèi)代碼的線程安全性。

(二)修飾靜態(tài)方法

當(dāng)synchronized修飾靜態(tài)方法時(shí),鎖對(duì)象是該類的Class對(duì)象。因?yàn)殪o態(tài)方法屬于類級(jí)別,不依賴于具體的對(duì)象實(shí)例,所以使用類的Class對(duì)象作為鎖。示例如下:

public class StaticSynchronizedExample {
    public static synchronized void staticSynchronizedMethod() {
        System.out.println("線程 " + Thread.currentThread().getName() + " 進(jìn)入靜態(tài)同步方法");
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("線程 " + Thread.currentThread().getName() + " 退出靜態(tài)同步方法");
    }
}

多個(gè)線程調(diào)用staticSynchronizedMethod時(shí),會(huì)對(duì)類的Class對(duì)象進(jìn)行加鎖,從而實(shí)現(xiàn)線程同步。

(三)修飾代碼塊

synchronized還可以修飾代碼塊,此時(shí)需要顯式指定鎖對(duì)象。鎖對(duì)象可以是任意對(duì)象,只要保證在需要同步的代碼塊中使用相同的鎖對(duì)象即可。比如:

public class BlockSynchronizedExample {
    private Object lock = new Object();
    public void blockSynchronized() {
        synchronized (lock) {
            System.out.println("線程 " + Thread.currentThread().getName() + " 進(jìn)入同步代碼塊");
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("線程 " + Thread.currentThread().getName() + " 退出同步代碼塊");
        }
    }
}

在這個(gè)例子中,lock對(duì)象作為同步代碼塊的鎖,多個(gè)線程訪問(wèn)blockSynchronized方法時(shí),會(huì)競(jìng)爭(zhēng)lock對(duì)象的鎖。

二、synchronized 的鎖升級(jí)

為了提高synchronized的性能,JVM 引入了鎖升級(jí)機(jī)制,從無(wú)鎖狀態(tài)開(kāi)始,根據(jù)競(jìng)爭(zhēng)情況逐步升級(jí)為偏向鎖、輕量級(jí)鎖和重量級(jí)鎖。

(一)無(wú)鎖

無(wú)鎖狀態(tài)是最基本的狀態(tài),當(dāng)沒(méi)有線程競(jìng)爭(zhēng)鎖時(shí),對(duì)象處于無(wú)鎖狀態(tài)。此時(shí),線程可以直接訪問(wèn)被synchronized修飾的代碼,無(wú)需進(jìn)行任何加鎖操作,因此性能最高。

(二)偏向鎖

當(dāng)一個(gè)線程首次訪問(wèn)被synchronized修飾的代碼時(shí),JVM 會(huì)將對(duì)象頭中的鎖標(biāo)志位設(shè)置為偏向鎖模式,并將該線程的 ID 記錄在對(duì)象頭中。此后,當(dāng)該線程再次訪問(wèn)同一對(duì)象的同步代碼時(shí),無(wú)需進(jìn)行額外的加鎖操作,直接進(jìn)入同步代碼塊,因?yàn)?JVM 認(rèn)為該線程很可能會(huì)再次訪問(wèn)。偏向鎖的存在減少了無(wú)競(jìng)爭(zhēng)情況下的鎖開(kāi)銷。

(三)輕量級(jí)鎖

當(dāng)有第二個(gè)線程試圖訪問(wèn)同一個(gè)對(duì)象的同步代碼時(shí),偏向鎖會(huì)升級(jí)為輕量級(jí)鎖。JVM 會(huì)在當(dāng)前線程的棧幀中創(chuàng)建一個(gè)鎖記錄(Lock Record),并將對(duì)象頭中的 Mark Word 復(fù)制到鎖記錄中,然后嘗試使用 CAS(Compare - And - Swap,比較并交換)操作將對(duì)象頭的 Mark Word 替換為指向鎖記錄的指針。如果 CAS 操作成功,當(dāng)前線程就獲得了輕量級(jí)鎖,可以進(jìn)入同步代碼塊;如果失敗,說(shuō)明存在競(jìng)爭(zhēng),輕量級(jí)鎖會(huì)升級(jí)為重量級(jí)鎖。

(四)重量級(jí)鎖

當(dāng)輕量級(jí)鎖競(jìng)爭(zhēng)失敗,即多個(gè)線程同時(shí)競(jìng)爭(zhēng)鎖時(shí),會(huì)升級(jí)為重量級(jí)鎖。此時(shí),JVM 會(huì)使用操作系統(tǒng)的互斥量(Mutex)來(lái)實(shí)現(xiàn)鎖機(jī)制,線程會(huì)進(jìn)入阻塞狀態(tài),等待鎖的釋放。重量級(jí)鎖的性能相對(duì)較低,因?yàn)榫€程的阻塞和喚醒需要操作系統(tǒng)的干預(yù),會(huì)帶來(lái)較大的開(kāi)銷。

鎖升級(jí)的過(guò)程是 JVM 根據(jù)實(shí)際的線程競(jìng)爭(zhēng)情況動(dòng)態(tài)調(diào)整的,目的是在保證線程安全性的同時(shí),盡可能提高synchronized的性能。

總之,synchronized是 Java 并發(fā)編程中實(shí)現(xiàn)線程同步的重要手段,理解其使用方式和鎖升級(jí)機(jī)制,對(duì)于編寫(xiě)高效、安全的多線程程序具有重要意義。在實(shí)際開(kāi)發(fā)中,我們應(yīng)該根據(jù)具體的場(chǎng)景合理使用synchronized,并注意鎖的粒度和性能優(yōu)化,以充分發(fā)揮多線程的優(yōu)勢(shì)。

到此這篇關(guān)于Java 中 synchronized 的使用和鎖升級(jí)的文章就介紹到這了,更多相關(guān)Java synchronized 使用內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • springboot登陸頁(yè)面圖片驗(yàn)證碼簡(jiǎn)單的web項(xiàng)目實(shí)現(xiàn)

    springboot登陸頁(yè)面圖片驗(yàn)證碼簡(jiǎn)單的web項(xiàng)目實(shí)現(xiàn)

    這篇文章主要介紹了springboot登陸頁(yè)面圖片驗(yàn)證碼簡(jiǎn)單的web項(xiàng)目實(shí)現(xiàn),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2019-04-04
  • linux用java -jar啟動(dòng)jar包緩慢的問(wèn)題

    linux用java -jar啟動(dòng)jar包緩慢的問(wèn)題

    這篇文章主要介紹了linux用java -jar啟動(dòng)jar包緩慢的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,
    2023-09-09
  • Springboot與vue實(shí)例講解實(shí)現(xiàn)前后端分離的人事管理系統(tǒng)

    Springboot與vue實(shí)例講解實(shí)現(xiàn)前后端分離的人事管理系統(tǒng)

    這篇文章主要介紹了如何用Java實(shí)現(xiàn)企業(yè)人事管理系統(tǒng),文中采用springboot+vue實(shí)現(xiàn)前后端分離,感興趣的小伙伴可以學(xué)習(xí)一下
    2022-06-06
  • java CompletableFuture實(shí)現(xiàn)異步編排詳解

    java CompletableFuture實(shí)現(xiàn)異步編排詳解

    這篇文章主要為大家介紹了java CompletableFuture實(shí)現(xiàn)異步編排詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-01-01
  • SpringBoot中定時(shí)任務(wù)的使用方法解析

    SpringBoot中定時(shí)任務(wù)的使用方法解析

    這篇文章主要介紹了SpringBoot中定時(shí)任務(wù)的使用方法解析,@EnableScheduling?注解,它的作用是發(fā)現(xiàn)注解?@Scheduled的任務(wù)并由后臺(tái)執(zhí)行,沒(méi)有它的話將無(wú)法執(zhí)行定時(shí)任務(wù),需要的朋友可以參考下
    2024-01-01
  • RocketMQ中消費(fèi)者的消費(fèi)進(jìn)度管理

    RocketMQ中消費(fèi)者的消費(fèi)進(jìn)度管理

    這篇文章主要介紹了RocketMQ中消費(fèi)者的消費(fèi)進(jìn)度管理,業(yè)務(wù)實(shí)現(xiàn)消費(fèi)回調(diào)的時(shí)候,當(dāng)且僅當(dāng)此回調(diào)函數(shù)返回ConsumeConcurrentlyStatus.CONSUME_SUCCESS ,RocketMQ才會(huì)認(rèn)為這批消息(默認(rèn)是1條)是消費(fèi)完成的,需要的朋友可以參考下
    2023-10-10
  • SpringBoot實(shí)現(xiàn)發(fā)送郵件功能過(guò)程圖解

    SpringBoot實(shí)現(xiàn)發(fā)送郵件功能過(guò)程圖解

    這篇文章主要介紹了SpringBoot實(shí)現(xiàn)發(fā)送郵件功能過(guò)程圖解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-03-03
  • Spring Cache框架應(yīng)用介紹

    Spring Cache框架應(yīng)用介紹

    我們一定聽(tīng)說(shuō)過(guò)"緩存無(wú)敵"的話,特別是在大型互聯(lián)網(wǎng)公司,"查多寫(xiě)少"的場(chǎng)景屢見(jiàn)不鮮。Spring Cache是作用在方法上的,其核心思想是,當(dāng)我們?cè)谡{(diào)用一個(gè)緩存方法時(shí)會(huì)把該方法參數(shù)和返回結(jié)果作為一個(gè)鍵值對(duì)存在緩存中
    2022-09-09
  • 在eclipse中使用SVN的方法(圖文)

    在eclipse中使用SVN的方法(圖文)

    這篇文章主要介紹了在eclipse中使用SVN的方法(圖文),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-08-08
  • 往DAO類中注入@PersistenceContext和@Resource的區(qū)別詳解

    往DAO類中注入@PersistenceContext和@Resource的區(qū)別詳解

    這篇文章主要介紹了往DAO類中注入@PersistenceContext和@Resource的區(qū)別詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-02-02

最新評(píng)論