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

Java 中 synchronized 的使用方式和鎖升級

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

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

一、synchronized 的使用方式

(一)修飾普通方法

當(dāng)synchronized修飾一個普通方法時,鎖對象是當(dāng)前對象(this)。也就是說,當(dāng)一個線程進(jìn)入該方法時,會自動獲取當(dāng)前對象的鎖,其他線程想要進(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是一個同步方法,多個線程同時調(diào)用該方法時,會依次排隊執(zhí)行,保證了方法內(nèi)代碼的線程安全性。

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

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

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)同步方法");
    }
}

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

(三)修飾代碼塊

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

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() + " 退出同步代碼塊");
        }
    }
}

在這個例子中,lock對象作為同步代碼塊的鎖,多個線程訪問blockSynchronized方法時,會競爭lock對象的鎖。

二、synchronized 的鎖升級

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

(一)無鎖

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

(二)偏向鎖

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

(三)輕量級鎖

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

(四)重量級鎖

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

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

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

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

相關(guān)文章

  • springboot登陸頁面圖片驗證碼簡單的web項目實現(xiàn)

    springboot登陸頁面圖片驗證碼簡單的web項目實現(xiàn)

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

    linux用java -jar啟動jar包緩慢的問題

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

最新評論