最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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的性能,引入了鎖升級機制。下面我們就來詳細介紹ynchronized的使用和鎖升級過程。

一、synchronized 的使用方式

(一)修飾普通方法

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

public class SynchronizedExample {
    public synchronized void synchronizedMethod() {
        // 線程同步的代碼邏輯
        System.out.println("線程 " + Thread.currentThread().getName() + " 進入同步方法");
        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() + " 進入靜態(tài)同步方法");
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("線程 " + Thread.currentThread().getName() + " 退出靜態(tài)同步方法");
    }
}

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

(三)修飾代碼塊

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

public class BlockSynchronizedExample {
    private Object lock = new Object();
    public void blockSynchronized() {
        synchronized (lock) {
            System.out.println("線程 " + Thread.currentThread().getName() + " 進入同步代碼塊");
            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修飾的代碼,無需進行任何加鎖操作,因此性能最高。

(二)偏向鎖

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

(三)輕量級鎖

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

(四)重量級鎖

當(dāng)輕量級鎖競爭失敗,即多個線程同時競爭鎖時,會升級為重量級鎖。此時,JVM 會使用操作系統(tǒng)的互斥量(Mutex)來實現(xià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)文章

最新評論

延庆县| 高台县| 葵青区| 宝山区| 秭归县| 滁州市| 黄冈市| 双辽市| 阳原县| 栾城县| 涪陵区| 通江县| 女性| 滨海县| 丘北县| 道孚县| 沂南县| 乌拉特前旗| 漳州市| 婺源县| 大连市| 财经| 雷山县| 津市市| 太保市| 资中县| 沽源县| 石屏县| 张家川| 明溪县| 曲麻莱县| 张掖市| 崇左市| 玉门市| 四子王旗| 德昌县| 桃园县| 江北区| 图们市| 湛江市| 邻水|