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

Java并發(fā)鎖機(jī)制知識(shí)總結(jié)(最新整理)

 更新時(shí)間:2025年11月29日 13:56:05   作者:秋風(fēng)不識(shí)晚間路  
Java?的鎖機(jī)制是并發(fā)編程的核心,用于解決多線程共享資源競(jìng)爭(zhēng)問(wèn)題,保證數(shù)據(jù)一致性和線程安全,這篇文章給大家介紹Java并發(fā)鎖機(jī)制知識(shí)總結(jié),感興趣的朋友跟隨小編一起看看吧

并發(fā)鎖機(jī)制知識(shí)總結(jié)

Java 的鎖機(jī)制是并發(fā)編程的核心,用于解決多線程共享資源競(jìng)爭(zhēng)問(wèn)題,保證數(shù)據(jù)一致性和線程安全。Java 提供了內(nèi)置鎖(synchronized)顯式鎖(Lock 接口) 等多種鎖實(shí)現(xiàn),同時(shí)衍生出偏向鎖、輕量級(jí)鎖、重量級(jí)鎖等優(yōu)化機(jī)制,以及可重入鎖、公平鎖、讀寫(xiě)鎖等功能分類(lèi)。

一、鎖的核心作用

  • 互斥性:同一時(shí)間只有一個(gè)線程能持有鎖,訪問(wèn)共享資源(解決 “競(jìng)態(tài)條件”)。
  • 可見(jiàn)性:持有鎖的線程修改共享資源后,釋放鎖時(shí)會(huì)將修改同步到主內(nèi)存;其他線程獲取鎖時(shí)會(huì)從主內(nèi)存讀取最新值(避免 “緩存一致性問(wèn)題”)。
  • 有序性:禁止指令重排序(避免多線程下的 “指令重排導(dǎo)致的邏輯錯(cuò)亂”)。

二、Java 鎖的分類(lèi)

(一)按實(shí)現(xiàn)方式:內(nèi)置鎖 vs 顯式鎖

1. 內(nèi)置鎖:synchronized(JVM 層面實(shí)現(xiàn))

synchronized 是 Java 原生的隱式鎖,基于 對(duì)象監(jiān)視器(Monitor) 實(shí)現(xiàn),無(wú)需手動(dòng)釋放,簡(jiǎn)單易用、線程安全。

(1)使用場(chǎng)景

(2)示例代碼

public class SynchronizedDemo {
    // 1. 實(shí)例方法鎖(鎖:this)
    public synchronized void method1() {
        // 共享資源操作
    }
    // 2. 靜態(tài)方法鎖(鎖:SynchronizedDemo.class)
    public static synchronized void method2() {
        // 共享資源操作
    }
    // 3. 代碼塊鎖(鎖:自定義對(duì)象)
    private final Object lock = new Object();
    public void method3() {
        synchronized (lock) {
            // 共享資源操作
        }
    }
}

(3)核心特性

(4)JVM 優(yōu)化:鎖升級(jí)(無(wú)鎖 → 偏向鎖 → 輕量級(jí)鎖 → 重量級(jí)鎖)

為了平衡性能和并發(fā)安全,JVM 對(duì) synchronized 進(jìn)行了鎖升級(jí)優(yōu)化(從低開(kāi)銷(xiāo)到高開(kāi)銷(xiāo)逐步過(guò)渡):

鎖升級(jí)是不可逆的(一旦升級(jí)為重量級(jí)鎖,不會(huì)降級(jí))。

2. 顯式鎖:Lock 接口(Java 代碼層面實(shí)現(xiàn))

java.util.concurrent.locks.Lock 是 JDK 1.5 引入的顯式鎖,提供比 synchronized 更靈活的功能(如可中斷、超時(shí)獲取、公平鎖等),但需手動(dòng)釋放鎖(否則會(huì)導(dǎo)致死鎖)。

(1)核心方法

方法作用
lock()獲取鎖(阻塞,不可中斷)
lockInterruptibly()獲取鎖(可被中斷,拋出 InterruptedException
tryLock()嘗試獲取鎖(非阻塞,成功返回 true,失敗返回 false
tryLock(long time, TimeUnit unit)超時(shí)獲取鎖(超時(shí)未獲取則返回 false
unlock()釋放鎖(必須在 finally 中調(diào)用)
newCondition()創(chuàng)建條件變量(實(shí)現(xiàn)線程等待 / 喚醒)

(2)常用實(shí)現(xiàn)類(lèi)

(3)示例代碼(ReentrantLock)

import java.util.concurrent.locks.ReentrantLock;
public class LockDemo {
    // 創(chuàng)建非公平鎖(默認(rèn)),若要公平鎖:new ReentrantLock(true)
    private final ReentrantLock lock = new ReentrantLock();
    public void method() {
        // 1. 獲取鎖(必須手動(dòng)獲取)
        lock.lock();
        try {
            // 共享資源操作
        } finally {
            // 2. 釋放鎖(必須在 finally 中釋放,避免鎖泄漏)
            lock.unlock();
        }
    }
    // 可中斷獲取鎖示例
    public void interruptibleMethod() throws InterruptedException {
        lock.lockInterruptibly(); // 線程可被中斷
        try {
            // 共享資源操作
        } finally {
            lock.unlock();
        }
    }
}

(4)核心特性

(二)按功能特性分類(lèi)

1. 可重入鎖 vs 不可重入鎖

2. 公平鎖 vs 非公平鎖

3. 讀寫(xiě)鎖(ReentrantReadWriteLock)

針對(duì) “讀多寫(xiě)少” 場(chǎng)景優(yōu)化,分離讀鎖(共享鎖)寫(xiě)鎖(排他鎖)

import java.util.concurrent.locks.ReentrantReadWriteLock;
public class ReadWriteLockDemo {
    private final ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();
    private final ReentrantReadWriteLock.ReadLock readLock = rwLock.readLock();
    private final ReentrantReadWriteLock.WriteLock writeLock = rwLock.writeLock();
    private int data;
    // 讀操作(共享鎖)
    public int readData() {
        readLock.lock();
        try {
            return data;
        } finally {
            readLock.unlock();
        }
    }
    // 寫(xiě)操作(排他鎖)
    public void writeData(int value) {
        writeLock.lock();
        try {
            data = value;
        } finally {
            writeLock.unlock();
        }
    }
}

4. 樂(lè)觀鎖 vs 悲觀鎖

(三)其他特殊鎖

1. 自旋鎖(SpinLock)

線程獲取鎖失敗時(shí),不立即阻塞,而是循環(huán)(自旋)嘗試獲取鎖(避免線程上下文切換開(kāi)銷(xiāo))。

2. 偏向鎖 / 輕量級(jí)鎖 / 重量級(jí)鎖(JVM 層面的鎖優(yōu)化)

見(jiàn)前文 synchronized 的鎖升級(jí)機(jī)制,核心是 “按需升級(jí)”,平衡性能和并發(fā)安全。

3. StampedLock(樂(lè)觀讀鎖)

JDK 1.8 引入,性能優(yōu)于 ReentrantReadWriteLock,支持三種模式:

三、synchronized vs ReentrantLock 對(duì)比

特性synchronizedReentrantLock
實(shí)現(xiàn)層面JVM 層面(底層是 Monitor)Java 代碼層面(AQS 框架)
可重入性支持支持
公平性僅非公平鎖公平 / 非公平可選
可中斷性不支持支持(lockInterruptibly ())
超時(shí)獲取不支持支持(tryLock (time))
條件變量僅一個(gè)(wait ()/notify ())多個(gè)(newCondition ())
鎖釋放自動(dòng)釋放(退出同步塊 / 方法)手動(dòng)釋放(必須在 finally 中 unlock ())
性能JDK 1.6 后優(yōu)化(鎖升級(jí)),性能接近 ReentrantLock高(靈活控制)
適用場(chǎng)景簡(jiǎn)單場(chǎng)景(無(wú)需復(fù)雜功能)復(fù)雜場(chǎng)景(需中斷、超時(shí)、公平鎖等)

四、鎖的使用注意事項(xiàng)

總結(jié)

Java 鎖機(jī)制的核心是解決共享資源競(jìng)爭(zhēng),提供了從簡(jiǎn)單到復(fù)雜的多種實(shí)現(xiàn):

使用鎖時(shí)需平衡線程安全性能,避免死鎖、鎖粒度過(guò)大等問(wèn)題,根據(jù)實(shí)際場(chǎng)景選擇合適的鎖類(lèi)型。
最后祝各位開(kāi)發(fā)者工作順利,萬(wàn)事如意。

  • 修飾實(shí)例方法:鎖是當(dāng)前對(duì)象(this)。
  • 修飾靜態(tài)方法:鎖是當(dāng)前類(lèi)的 Class 對(duì)象(全局鎖)。
  • 修飾代碼塊:鎖是括號(hào)中的對(duì)象(可自定義鎖對(duì)象,靈活度更高)。
  • 可重入:同一線程可多次獲取同一把鎖(避免死鎖,如遞歸調(diào)用 synchronized 方法)。
  • 非公平鎖:線程獲取鎖的順序不按請(qǐng)求順序(默認(rèn),性能優(yōu)先)。
  • 自動(dòng)釋放:線程退出同步塊 / 方法時(shí),無(wú)論正常退出還是異常退出,鎖都會(huì)自動(dòng)釋放(無(wú)需手動(dòng)處理)。
  • 不可中斷:線程獲取鎖時(shí)若被阻塞,只能等待鎖釋放或一直阻塞(無(wú)法主動(dòng)中斷)。
  • 無(wú)鎖:無(wú)線程競(jìng)爭(zhēng)時(shí),無(wú)需加鎖(直接執(zhí)行)。
  • 偏向鎖:?jiǎn)尉€程重復(fù)獲取鎖時(shí),僅記錄線程 ID(避免 CAS 操作,開(kāi)銷(xiāo)極低)。
    • 觸發(fā)條件:只有一個(gè)線程訪問(wèn)同步資源。
    • 撤銷(xiāo):當(dāng)有第二個(gè)線程競(jìng)爭(zhēng)時(shí),偏向鎖會(huì)升級(jí)為輕量級(jí)鎖。
  • 輕量級(jí)鎖: 多個(gè)線程交替訪問(wèn)鎖(無(wú)激烈競(jìng)爭(zhēng)),通過(guò)CAS(Compare and Swap)嘗試獲取鎖(自旋等待,避免阻塞線程)。
    • 自旋次數(shù):默認(rèn) 10 次(可通過(guò) -XX:PreBlockSpin 調(diào)整),自旋失敗則升級(jí)為重量級(jí)鎖。
  • 重量級(jí)鎖:多個(gè)線程激烈競(jìng)爭(zhēng)鎖(自旋無(wú)效),通過(guò)操作系統(tǒng)的 互斥量(Mutex) 實(shí)現(xiàn)(線程會(huì)阻塞,開(kāi)銷(xiāo)最高)。
  • ReentrantLock:可重入鎖(最常用),支持公平鎖和非公平鎖(默認(rèn)非公平)。
  • ReentrantReadWriteLock:讀寫(xiě)鎖(分離讀鎖和寫(xiě)鎖,提高讀多寫(xiě)少場(chǎng)景的并發(fā)性能)。
  • StampedLock:JDK 1.8 引入的樂(lè)觀讀鎖(性能優(yōu)于讀寫(xiě)鎖,支持樂(lè)觀讀、寫(xiě)鎖、悲觀讀鎖)。
  • 可重入:與 synchronized 一致,同一線程可多次獲取鎖(鎖計(jì)數(shù)器遞增,釋放時(shí)遞減至 0 才釋放)。
  • 公平 / 非公平可選:構(gòu)造函數(shù)傳入 true 則為公平鎖(按線程請(qǐng)求順序分配鎖,性能略低),默認(rèn)非公平鎖(性能優(yōu)先)。
  • 可中斷:支持 lockInterruptibly() 中斷阻塞中的線程(避免無(wú)限等待)。
  • 超時(shí)獲取:通過(guò) tryLock(time) 避免線程永久阻塞。
  • 條件變量:通過(guò) newCondition() 創(chuàng)建多個(gè)條件變量(比 synchronizedwait()/notify() 更靈活,可精準(zhǔn)喚醒特定線程)。
  • 可重入鎖:同一線程可多次獲取同一把鎖(如synchronized、ReentrantLock),避免遞歸調(diào)用或嵌套同步時(shí)的死鎖。

    • 原理:鎖內(nèi)部維護(hù)一個(gè) “線程持有計(jì)數(shù)”,線程首次獲取時(shí)計(jì)數(shù)為 1,再次獲取時(shí)計(jì)數(shù)遞增,釋放時(shí)計(jì)數(shù)遞減,計(jì)數(shù)為 0 時(shí)鎖釋放。
  • 不可重入鎖:同一線程無(wú)法多次獲取同一把鎖(如簡(jiǎn)單的 SpinLock 實(shí)現(xiàn)),容易導(dǎo)致死鎖,極少使用。

  • 公平鎖:線程獲取鎖的順序嚴(yán)格按照 “請(qǐng)求順序”(FIFO),不會(huì)出現(xiàn)饑餓(每個(gè)線程都能最終獲取鎖)。
    • 實(shí)現(xiàn):維護(hù)一個(gè)等待隊(duì)列,新線程需加入隊(duì)列尾部,僅當(dāng)隊(duì)列頭部線程才能獲取鎖。
    • 缺點(diǎn):性能較低(頻繁切換線程上下文)。
  • 非公平鎖:線程獲取鎖時(shí)不按請(qǐng)求順序,允許 “插隊(duì)”(剛釋放鎖的線程可能再次獲取鎖,減少上下文切換)。
    • 優(yōu)點(diǎn):性能更高(默認(rèn)選擇,如 synchronized、ReentrantLock 默認(rèn))。
    • 缺點(diǎn):可能導(dǎo)致部分線程長(zhǎng)期無(wú)法獲取鎖(饑餓)。
  • 讀鎖(共享鎖):多個(gè)線程可同時(shí)獲取讀鎖(讀操作不互斥)。
  • 寫(xiě)鎖(排他鎖):僅一個(gè)線程可獲取寫(xiě)鎖(寫(xiě)操作與讀 / 寫(xiě)操作互斥)。
  • 核心規(guī)則:讀鎖持有期間,寫(xiě)鎖無(wú)法獲??;寫(xiě)鎖持有期間,讀鎖和寫(xiě)鎖均無(wú)法獲取。
  • 示例代碼:
  • 悲觀鎖:認(rèn)為并發(fā)競(jìng)爭(zhēng)必然發(fā)生,每次訪問(wèn)共享資源都先加鎖(如synchronized、ReentrantLock)。
    • 優(yōu)點(diǎn):簡(jiǎn)單可靠,適合寫(xiě)操作多的場(chǎng)景。
    • 缺點(diǎn):阻塞線程,性能開(kāi)銷(xiāo)高。
  • 樂(lè)觀鎖:認(rèn)為并發(fā)競(jìng)爭(zhēng)很少發(fā)生,不加鎖直接訪問(wèn)資源,僅在修改時(shí)通過(guò) CAS 驗(yàn)證是否有沖突(沖突則重試)。
    • 實(shí)現(xiàn):AtomicInteger(基于 CAS)、StampedLock(樂(lè)觀讀模式)、數(shù)據(jù)庫(kù)的版本號(hào)機(jī)制。
    • 優(yōu)點(diǎn):非阻塞,性能高,適合讀操作多的場(chǎng)景。
    • 缺點(diǎn):存在 “ABA 問(wèn)題”(可通過(guò)版本號(hào) / 時(shí)間戳解決),重試次數(shù)過(guò)多會(huì)消耗 CPU。
  • 適用場(chǎng)景:鎖持有時(shí)間短、并發(fā)度低的場(chǎng)景(如 JVM 輕量級(jí)鎖的自旋階段)。
  • 缺點(diǎn):自旋期間占用 CPU,若鎖持有時(shí)間長(zhǎng),會(huì)浪費(fèi) CPU 資源。
  • 樂(lè)觀讀模式:無(wú)鎖訪問(wèn),讀取后驗(yàn)證版本號(hào)(無(wú)沖突則成功,有沖突則升級(jí)為悲觀讀鎖)。
  • 悲觀讀模式:共享鎖(類(lèi)似讀寫(xiě)鎖的讀鎖)。
  • 寫(xiě)模式:排他鎖(類(lèi)似讀寫(xiě)鎖的寫(xiě)鎖)。
  • 優(yōu)點(diǎn):樂(lè)觀讀模式下無(wú)鎖競(jìng)爭(zhēng),性能極高;缺點(diǎn):不支持可重入,使用復(fù)雜。
  1. 避免死鎖:
    • 手動(dòng)釋放鎖(ReentrantLock 必須在 finally 中 unlock ())。
    • 避免嵌套鎖(或保證嵌套鎖的獲取順序一致)。
    • 避免長(zhǎng)時(shí)間持有鎖(減少鎖競(jìng)爭(zhēng))。
  2. 選擇合適的鎖類(lèi)型:
    • 讀多寫(xiě)少:用 ReentrantReadWriteLockStampedLock
    • 簡(jiǎn)單場(chǎng)景:用 synchronized(無(wú)需手動(dòng)管理鎖)。
    • 復(fù)雜場(chǎng)景(中斷、超時(shí)、公平鎖):用 ReentrantLock。
  3. 減少鎖粒度:
    • 避免鎖覆蓋整個(gè)方法(僅對(duì)共享資源的操作加鎖,如 synchronized 代碼塊而非方法)。
    • 示例:用 synchronized (lock) 替代 synchronized method()(僅鎖定關(guān)鍵代碼)。
  4. 避免鎖競(jìng)爭(zhēng):
    • 無(wú)狀態(tài)對(duì)象無(wú)需加鎖(無(wú)共享資源)。
    • 共享資源盡量設(shè)計(jì)為不可變(如 StringInteger)。
    • 用局部變量替代共享變量(線程私有,無(wú)需鎖)。
  • 基礎(chǔ)場(chǎng)景:優(yōu)先使用 synchronized(簡(jiǎn)單、安全、JVM 優(yōu)化充分)。
  • 復(fù)雜場(chǎng)景:使用 ReentrantLock(可中斷、超時(shí)、公平鎖)或 ReentrantReadWriteLock(讀多寫(xiě)少)。
  • 性能優(yōu)化:利用 JVM 鎖升級(jí)(synchronized)、樂(lè)觀鎖(StampedLock、Atomic 類(lèi))減少鎖開(kāi)銷(xiāo)。

到此這篇關(guān)于Java-并發(fā)鎖機(jī)制知識(shí)總結(jié)的文章就介紹到這了,更多相關(guān)Java并發(fā)鎖機(jī)制內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java微信公眾平臺(tái)開(kāi)發(fā)(1) 接入微信公眾平臺(tái)

    Java微信公眾平臺(tái)開(kāi)發(fā)(1) 接入微信公眾平臺(tái)

    這篇文章主要為大家詳細(xì)介紹了Java微信公眾平臺(tái)開(kāi)發(fā)第一步,接入微信公眾平臺(tái),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-04-04
  • java  Lock接口詳解及實(shí)例代碼

    java Lock接口詳解及實(shí)例代碼

    這篇文章主要介紹了java Lock接口詳解及實(shí)例代碼的相關(guān)資料,需要的朋友可以參考下
    2017-01-01
  • Mybatis環(huán)境配置及測(cè)試詳解

    Mybatis環(huán)境配置及測(cè)試詳解

    這篇文章主要介紹了Mybatis環(huán)境配置及測(cè)試詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-01-01
  • Java Ribbon負(fù)載均衡詳細(xì)講解

    Java Ribbon負(fù)載均衡詳細(xì)講解

    Ribbon其實(shí)就是一個(gè)軟負(fù)載均衡的客戶(hù)端組件,他可以和其他所需請(qǐng)求的客戶(hù)端結(jié)合使用,這篇文章主要介紹了Ribbon負(fù)載均衡服務(wù)調(diào)用案例代碼,需要的朋友可以參考下
    2023-01-01
  • logback 自定義Pattern模板教程

    logback 自定義Pattern模板教程

    這篇文章主要介紹了logback 自定義Pattern模板教程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • java構(gòu)造方法的作用總結(jié)

    java構(gòu)造方法的作用總結(jié)

    在本篇文章里小編給大家整理了關(guān)于java構(gòu)造方法的相關(guān)知識(shí)點(diǎn)以及實(shí)例代碼,有需要的朋友們可以學(xué)習(xí)下。
    2019-07-07
  • java泛型類(lèi)的定義與使用詳解

    java泛型類(lèi)的定義與使用詳解

    這篇文章主要為大家詳細(xì)介紹了java泛型類(lèi)定義與使用的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-08-08
  • SpringBoot如何集成i18n(多語(yǔ)言)

    SpringBoot如何集成i18n(多語(yǔ)言)

    這篇文章主要介紹了SpringBoot如何集成i18n(多語(yǔ)言)問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-04-04
  • Java RestTemplate post請(qǐng)求參數(shù)問(wèn)題及解決

    Java RestTemplate post請(qǐng)求參數(shù)問(wèn)題及解決

    作者解決了用JavaRestTemplate進(jìn)行POST請(qǐng)求時(shí)遇到的參數(shù)傳遞問(wèn)題,發(fā)現(xiàn)使用MultiValueMap比Map更合適,同時(shí)強(qiáng)調(diào)了請(qǐng)求頭的數(shù)據(jù)類(lèi)型和URL的占位符在GET請(qǐng)求中如何正確使用
    2025-12-12
  • Java使用Fastjson2處理JSON字段大小寫(xiě)不一致的優(yōu)雅方案

    Java使用Fastjson2處理JSON字段大小寫(xiě)不一致的優(yōu)雅方案

    這篇文章主要為大家詳細(xì)介紹了Java使用Fastjson2處理JSON字段大小寫(xiě)不一致的優(yōu)雅方案,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2026-04-04

最新評(píng)論

筠连县| 论坛| 瓮安县| 兰考县| 铁岭市| 大兴区| 惠来县| 永嘉县| 庆阳市| 长岛县| 河间市| 会东县| 弋阳县| 米脂县| 临清市| 奇台县| 邢台市| 邵阳县| 武鸣县| 彩票| 汝南县| 浦城县| 芒康县| 尚志市| 鹤山市| 从化市| 辽源市| 宾阳县| 宕昌县| 陇南市| 锦州市| 高邮市| 来安县| 竹北市| 南乐县| 奈曼旗| 仁寿县| 洛川县| 长乐市| 崇明县| 邵阳市|