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

一文詳細(xì)講解Java中有哪些鎖

 更新時間:2025年07月07日 09:12:49   作者:xzkyd outpaper  
在Java編程中鎖是一種同步機(jī)制,用于確保多個線程在訪問共享資源時的一致性和正確性,這篇文章主要介紹了Java中有哪些鎖的相關(guān)資料,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下

1. synchronized 鎖

作用
synchronized 是 Java 最基礎(chǔ)的鎖機(jī)制,用于實現(xiàn)方法或代碼塊的同步,保證多線程環(huán)境下的原子性、可見性和有序性。

使用方式

  • 對象鎖:修飾實例方法或代碼塊(鎖對象為當(dāng)前實例 this)。

    public synchronized void method() { ... } // 實例方法鎖
    public void method() {
        synchronized (this) { ... }          // 代碼塊鎖(對象鎖)
    }
  • 類鎖:修飾靜態(tài)方法或代碼塊(鎖對象為類的 Class 對象)。

    public static synchronized void staticMethod() { ... } // 靜態(tài)方法鎖
    public void method() {
        synchronized (MyClass.class) { ... } // 代碼塊鎖(類鎖)
    }

特點

  • 隱式鎖:自動獲取和釋放鎖,無需手動管理。

  • 可重入:線程可重復(fù)獲取同一把鎖。

  • 非公平鎖:默認(rèn)搶占式獲取鎖,不保證等待時間長的線程優(yōu)先獲取。

適用場景
簡單同步需求,如單例模式的雙重檢查鎖。

2. ReentrantLock(可重入鎖)

作用
ReentrantLock 是 java.util.concurrent.locks 包下的顯式鎖,提供比 synchronized 更靈活的鎖控制。

使用方式

ReentrantLock lock = new ReentrantLock();
public void method() {
    lock.lock(); // 手動加鎖
    try {
        // 臨界區(qū)代碼
    } finally {
        lock.unlock(); // 必須手動釋放
    }
}

核心功能

  • 嘗試非阻塞獲取鎖tryLock()。

  • 超時獲取鎖tryLock(long timeout, TimeUnit unit)。

  • 公平性選擇:構(gòu)造函數(shù)傳入 true 實現(xiàn)公平鎖(按等待順序分配鎖)。

  • 條件變量:配合 Condition 實現(xiàn)線程間協(xié)調(diào)(如生產(chǎn)者-消費者模型)。

優(yōu)缺點

  • 優(yōu)點:靈活,支持中斷、超時、公平鎖。

  • 缺點:需手動釋放鎖,編碼不當(dāng)易導(dǎo)致死鎖。

適用場景
需要復(fù)雜同步控制的場景,如多條件等待、鎖超時處理。

3. ReadWriteLock(讀寫鎖)

作用

允許多個線程同時讀,但寫線程獨占資源,適用于讀多寫少的場景。

實現(xiàn)類ReentrantReadWriteLock

使用方式

ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();
ReentrantReadWriteLock.ReadLock readLock = rwLock.readLock();
ReentrantReadWriteLock.WriteLock writeLock = rwLock.writeLock();

public void readData() {
    readLock.lock();
    try { ... } finally { readLock.unlock(); }
}

public void writeData() {
    writeLock.lock();
    try { ... } finally { writeLock.unlock(); }
}

特點

  • 讀共享:多個讀線程可同時訪問。

  • 寫?yīng)氄?/strong>:寫線程獲取鎖時,禁止其他讀/寫操作。

  • 鎖降級:寫鎖可降級為讀鎖(反之不可)。

適用場景
緩存系統(tǒng)、頻繁讀取但偶爾更新的數(shù)據(jù)結(jié)構(gòu)。

4. StampedLock(Java 8+)

作用

提供更靈活的讀寫鎖控制,支持樂觀讀、悲觀讀、寫鎖三種模式,性能優(yōu)于 ReadWriteLock。

使用方式

StampedLock stampedLock = new StampedLock();

// 樂觀讀(無鎖)
long stamp = stampedLock.tryOptimisticRead();
if (!stampedLock.validate(stamp)) { // 檢查是否發(fā)生寫操作
    stamp = stampedLock.readLock(); // 退化為悲觀讀
    try { ... } finally { stampedLock.unlockRead(stamp); }
}

// 寫鎖
long writeStamp = stampedLock.writeLock();
try { ... } finally { stampedLock.unlockWrite(writeStamp); }

特點

  • 樂觀讀:假設(shè)沒有寫操作,通過 validate() 驗證。

  • 鎖轉(zhuǎn)換:支持讀鎖與寫鎖的轉(zhuǎn)換(如 tryConvertToWriteLock())。

適用場景
讀多寫少且對性能要求極高的場景,但需謹(jǐn)慎處理鎖轉(zhuǎn)換邏輯。

5. 顯式鎖 vs 隱式鎖

維度顯式鎖(如 ReentrantLock)隱式鎖(synchronized)
鎖獲取方式手動調(diào)用 lock() 和 unlock()自動獲取和釋放
靈活性支持超時、中斷、公平鎖、條件變量僅支持非公平鎖,無超時或中斷機(jī)制
性能高并發(fā)場景下更優(yōu)優(yōu)化后性能接近顯式鎖(如鎖升級機(jī)制)
代碼復(fù)雜度需手動管理,易出錯自動管理,代碼簡潔

6. 鎖優(yōu)化策略(JVM 對 synchronized 的優(yōu)化)

  • 偏向鎖
    假設(shè)只有一個線程訪問同步塊,通過標(biāo)記線程 ID 避免 CAS 操作。
    適用場景:單線程重復(fù)訪問同步代碼。

  • 輕量級鎖
    當(dāng)多線程競爭時,通過 CAS 自旋嘗試獲取鎖(避免阻塞)。
    適用場景:低競爭、同步塊執(zhí)行時間短。

  • 重量級鎖
    競爭激烈時,線程進(jìn)入阻塞狀態(tài),依賴操作系統(tǒng)的互斥量(Mutex)管理。
    適用場景:高競爭、同步塊執(zhí)行時間長。

鎖升級流程

無鎖 → 偏向鎖 → 輕量級鎖 → 重量級鎖

7. 條件鎖(Condition)

作用
配合顯式鎖(如 ReentrantLock)使用,實現(xiàn)線程的等待/喚醒機(jī)制,類似 Object.wait() 和 Object.notify(),但更靈活。

使用方式

ReentrantLock lock = new ReentrantLock();
Condition condition = lock.newCondition();

public void await() throws InterruptedException {
    lock.lock();
    try {
        condition.await(); // 釋放鎖并等待
    } finally { lock.unlock(); }
}

public void signal() {
    lock.lock();
    try {
        condition.signal(); // 喚醒一個等待線程
    } finally { lock.unlock(); }
}

適用場景
生產(chǎn)者-消費者模型、多條件線程協(xié)調(diào)。

8. 分布式鎖

作用

在分布式系統(tǒng)中協(xié)調(diào)多節(jié)點對共享資源的訪問,防止并發(fā)沖突。

實現(xiàn)方式

  • Redis:通過 SETNX(或 RedLock 算法)實現(xiàn)。

    // 使用 Redisson 客戶端
    RLock lock = redisson.getLock("myLock");
    lock.lock();
    try { ... } finally { lock.unlock(); }
  • ZooKeeper:通過臨時有序節(jié)點實現(xiàn)。

  • 數(shù)據(jù)庫:利用唯一索引或樂觀鎖(版本號)。

核心挑戰(zhàn)

  • 死鎖預(yù)防:設(shè)置鎖超時時間。

  • 容錯性:避免單點故障(如 Redis 集群)。

總結(jié)

鎖類型核心特點適用場景
synchronized簡單、自動管理,支持鎖升級優(yōu)化簡單同步需求
ReentrantLock靈活,支持超時、公平鎖、條件變量復(fù)雜同步控制(如多條件等待)
ReadWriteLock讀寫分離,讀多寫少場景性能更優(yōu)緩存、頻繁讀的數(shù)據(jù)結(jié)構(gòu)
StampedLock高性能,支持樂觀讀極高并發(fā)讀場景
分布式鎖跨進(jìn)程、跨節(jié)點協(xié)調(diào)分布式系統(tǒng)資源共享

選擇建議

  • 優(yōu)先使用 synchronized(簡單場景)。

  • 需要靈活控制時選 ReentrantLock。

  • 讀多寫少用 ReadWriteLock 或 StampedLock

  • 分布式環(huán)境用 Redis/ZooKeeper 實現(xiàn)分布式鎖。

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

相關(guān)文章

  • Java調(diào)用linux shell腳本的方法

    Java調(diào)用linux shell腳本的方法

    這篇文章主要介紹了Java調(diào)用linux shell腳本的方法,需要的朋友可以參考下
    2015-02-02
  • SpringAOP+RabbitMQ+WebSocket實戰(zhàn)詳解

    SpringAOP+RabbitMQ+WebSocket實戰(zhàn)詳解

    這篇文章主要介紹了SpringAOP+RabbitMQ+WebSocket實戰(zhàn)詳解,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-11-11
  • 使用maven開發(fā)springboot項目時pom.xml常用配置(推薦)

    使用maven開發(fā)springboot項目時pom.xml常用配置(推薦)

    這篇文章主要介紹了使用maven開發(fā)springboot項目時的pom.xml常用配置,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-01-01
  • 詳談Jedis連接池的使用

    詳談Jedis連接池的使用

    下面小編就為大家?guī)硪黄斦凧edis連接池的使用。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-05-05
  • Java中的序列化(Serializable)和反序列化

    Java中的序列化(Serializable)和反序列化

    這篇文章主要介紹了Java中的序列化(Serializable)和反序列化,?JAVA序列化與反序列化就是JAVA對象與一串字節(jié)流之間的相互轉(zhuǎn)換,?我們在程序中創(chuàng)建的JAVA對象只存在于JVM中,需要的朋友可以參考下
    2023-09-09
  • java編程FinalReference與Finalizer原理示例詳解

    java編程FinalReference與Finalizer原理示例詳解

    這篇文章主要為大家介紹了java編程FinalReference與Finalizer的核心原理以及示例源碼的分析詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助
    2022-01-01
  • Java實現(xiàn)經(jīng)典游戲之大魚吃小魚

    Java實現(xiàn)經(jīng)典游戲之大魚吃小魚

    這篇文章主要為大家詳細(xì)介紹了如何利用Java語言實現(xiàn)經(jīng)典游戲之大魚吃小魚,文中的示例代碼講解詳細(xì),對我們學(xué)習(xí)Java游戲開發(fā)有一定幫助,需要的可以參考一下
    2022-08-08
  • Mybatis調(diào)用存儲過程的案例

    Mybatis調(diào)用存儲過程的案例

    這篇文章主要介紹了Mybatis如何調(diào)用存儲過程,本文通過示例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-07-07
  • 淺析Java基于Socket的文件傳輸案例

    淺析Java基于Socket的文件傳輸案例

    這篇文章主要針對Java基于Socket的文件傳輸案例進(jìn)行詳細(xì)解析,具有一定的參考價值,感興趣的朋友可以參考一下
    2016-02-02
  • Java如何調(diào)用C++ DLL庫

    Java如何調(diào)用C++ DLL庫

    本文重點給大家介紹java中調(diào)用c++ dll庫的方法,本文分步驟介紹的非常詳細(xì),感興趣的朋友可以參考下
    2016-06-06

最新評論