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

Java中鎖分類及在什么場景下使用

 更新時間:2026年01月27日 10:48:21   作者:城管不管  
文章詳細介紹了鎖的進階分類,如可重入鎖、樂觀鎖、公平鎖、讀寫鎖等,并提供了具體的代碼示例,最后,文章給出了實戰(zhàn)選型指南,幫助開發(fā)者根據(jù)具體業(yè)務場景選擇合適的鎖類型,以達到最優(yōu)的性能和可維護性,感興趣的朋友跟隨小編一起看看吧

一、基礎分類(按實現(xiàn)方式)

這是最核心的分類維度,直接決定鎖的使用方式和核心能力。

1. 內(nèi)置鎖(synchronized)- 隱式鎖

核心定義

Java 關鍵字,JVM 層面實現(xiàn)的隱式鎖(無需手動釋放),是最基礎、使用最廣泛的鎖。JDK1.6 后引入「鎖升級」機制,性能大幅提升。

核心特點

  • 可重入、默認非公平鎖;
  • 自動加鎖 / 解鎖(方法 / 代碼塊執(zhí)行完自動釋放,無需手動處理);
  • 底層依賴對象頭的Mark Word + 監(jiān)視器鎖(ObjectMonitor);
  • 支持鎖升級(偏向鎖→輕量級鎖→重量級鎖),適配不同并發(fā)場景。

適用場景

  • 簡單互斥場景(如方法 / 代碼塊的線程安全);
  • 并發(fā)度不高、代碼簡潔性優(yōu)先的場景;
  • 不需要靈活特性(如可中斷、超時獲取鎖)的場景;
  • 絕大多數(shù)普通業(yè)務場景(JVM 優(yōu)化后性能接近顯式鎖)。

代碼示例

public class SynchronizedDemo {
    // 1. 實例方法鎖(對象鎖):鎖當前實例對象
    public synchronized void objectLock() {
        System.out.println(Thread.currentThread().getName() + "獲取對象鎖");
        try { Thread.sleep(100); } catch (InterruptedException e) {}
    }
    // 2. 靜態(tài)方法鎖(類鎖):鎖當前類的Class對象
    public static synchronized void classLock() {
        System.out.println(Thread.currentThread().getName() + "獲取類鎖");
        try { Thread.sleep(100); } catch (InterruptedException e) {}
    }
    // 3. 代碼塊鎖:自定義鎖對象(靈活度最高)
    private final Object lockObj = new Object();
    public void blockLock() {
        synchronized (lockObj) {
            System.out.println(Thread.currentThread().getName() + "獲取代碼塊鎖");
            try { Thread.sleep(100); } catch (InterruptedException e) {}
        }
    }
    public static void main(String[] args) {
        SynchronizedDemo demo = new SynchronizedDemo();
        // 競爭同一對象鎖,串行執(zhí)行
        new Thread(demo::objectLock, "線程1").start();
        new Thread(demo::objectLock, "線程2").start();
    }
}

2. 顯式鎖(Lock 接口)- 手動鎖

核心定義

JUC 包下java.util.concurrent.locks.Lock接口的實現(xiàn)類,手動加鎖 / 釋放鎖(需在finally中釋放,避免死鎖),是 synchronized 的補充和增強。

核心實現(xiàn)類 & 特點

實現(xiàn)類核心特性
ReentrantLock可重入、支持公平 / 非公平、可中斷、超時獲取鎖
ReentrantReadWriteLock讀寫分離(讀共享、寫獨占)、可重入
StampedLock支持樂觀讀、讀寫鎖、寫鎖,性能優(yōu)于讀寫鎖

適用場景

  • 需要靈活鎖控制(如可中斷、超時獲取鎖、公平鎖)的場景;
  • 讀多寫少的高并發(fā)場景(選 ReentrantReadWriteLock/StampedLock);
  • 高并發(fā)、需要精細控制鎖生命周期的場景。

代碼示例(ReentrantLock)

import java.util.concurrent.locks.ReentrantLock;
public class ReentrantLockDemo {
    // 公平鎖(按請求順序獲取),默認非公平鎖(性能更高)
    private static final ReentrantLock lock = new ReentrantLock(true);
    public static void doTask() {
        // 1. 加鎖(可替換為lockInterruptibly():可中斷鎖)
        lock.lock();
        try {
            System.out.println(Thread.currentThread().getName() + "獲取鎖");
            // 模擬業(yè)務操作
            Thread.sleep(100);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt(); // 恢復中斷狀態(tài)
        } finally {
            // 2. 釋放鎖(必須放finally,否則死鎖)
            if (lock.isHeldByCurrentThread()) {
                lock.unlock();
                System.out.println(Thread.currentThread().getName() + "釋放鎖");
            }
        }
    }
    public static void main(String[] args) {
        new Thread(ReentrantLockDemo::doTask, "線程A").start();
        new Thread(ReentrantLockDemo::doTask, "線程B").start();
    }
}

二、進階分類(按鎖的核心特性)

基于鎖的行為和并發(fā)特性分類,幫你理解鎖的底層邏輯和適用場景。

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

類型定義示例適用場景
可重入鎖同一線程可多次獲取同一把鎖,不會死鎖synchronized、ReentrantLock所有業(yè)務場景(遞歸調(diào)用、同一線程多次操作共享資源)
不可重入鎖同一線程多次獲取同一鎖會死鎖自定義簡單自旋鎖(未處理重入)極少使用(僅嚴格限制鎖獲取次數(shù)的特殊場景)

可重入鎖示例(synchronized 遞歸調(diào)用)

public class ReentrantDemo {
    public synchronized void outer() {
        System.out.println("外層方法獲取鎖");
        inner(); // 同一線程再次獲取同一鎖,無死鎖
    }
    public synchronized void inner() {
        System.out.println("內(nèi)層方法獲取鎖");
    }
    public static void main(String[] args) {
        new ReentrantDemo().outer(); // 正常執(zhí)行,無死鎖
    }
}

2. 樂觀鎖 vs 悲觀鎖

這是并發(fā)設計思想的分類,而非具體鎖實現(xiàn)。

類型核心思想實現(xiàn)方式適用場景
悲觀鎖假設必有競爭,先鎖后執(zhí)行synchronized、ReentrantLock高沖突、寫多讀少(如庫存扣減、轉(zhuǎn)賬)
樂觀鎖假設無競爭,先執(zhí)行后檢測CAS(Atomic 類)、版本號低沖突、讀多寫少(如計數(shù)器、緩存更新)

樂觀鎖示例(CAS 實現(xiàn))

import java.util.concurrent.atomic.AtomicInteger;
public class OptimisticLockDemo {
    // CAS是樂觀鎖的核心實現(xiàn)
    private static final AtomicInteger count = new AtomicInteger(0);
    // 原子自增(無鎖,沖突時重試)
    public static void increment() {
        count.incrementAndGet();
    }
    public static void main(String[] args) throws InterruptedException {
        Runnable task = () -> {
            for (int i = 0; i < 1000; i++) increment();
        };
        Thread t1 = new Thread(task);
        Thread t2 = new Thread(task);
        t1.start(); t2.start();
        t1.join(); t2.join();
        System.out.println("最終計數(shù):" + count.get()); // 2000(線程安全)
    }
}

3. 公平鎖 vs 非公平鎖

類型定義示例適用場景
公平鎖按請求順序獲取鎖,先到先得ReentrantLock(true)對公平性要求高(如任務排隊、避免線程饑餓)
非公平鎖不按順序,線程可插隊獲取鎖synchronized、ReentrantLock()大部分場景(優(yōu)先性能,容忍輕微饑餓)

4. 讀寫鎖(ReentrantReadWriteLock)- 共享 + 獨占鎖

核心定義

將鎖拆分為「讀鎖(共享鎖)」和「寫鎖(獨占鎖)」,核心規(guī)則:

  • 讀 - 讀共享:多個線程可同時獲取讀鎖;
  • 讀 - 寫互斥:讀鎖和寫鎖不能同時持有;
  • 寫 - 寫互斥:多個線程不能同時獲取寫鎖。

適用場景

讀多寫少的場景(如緩存、配置讀取、商品詳情頁、數(shù)據(jù)查詢),相比普通獨占鎖,能大幅提升讀并發(fā)效率。

代碼示例

import java.util.concurrent.locks.ReentrantReadWriteLock;
public class ReadWriteLockDemo {
    private static final ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();
    private static final ReentrantReadWriteLock.ReadLock readLock = rwLock.readLock();
    private static final ReentrantReadWriteLock.WriteLock writeLock = rwLock.writeLock();
    private static int cacheData = 0; // 模擬緩存數(shù)據(jù)
    // 讀操作(共享鎖,多線程同時執(zhí)行)
    public static void readCache() {
        readLock.lock();
        try {
            System.out.println(Thread.currentThread().getName() + "讀取緩存:" + cacheData);
            Thread.sleep(200); // 模擬讀耗時
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        } finally {
            readLock.unlock();
        }
    }
    // 寫操作(獨占鎖,串行執(zhí)行)
    public static void updateCache(int newData) {
        writeLock.lock();
        try {
            System.out.println(Thread.currentThread().getName() + "更新緩存:" + newData);
            cacheData = newData;
            Thread.sleep(200); // 模擬寫耗時
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        } finally {
            writeLock.unlock();
        }
    }
    public static void main(String[] args) {
        // 5個讀線程(可同時執(zhí)行,并發(fā)效率高)
        for (int i = 0; i < 5; i++) {
            new Thread(ReadWriteLockDemo::readCache, "讀線程" + i).start();
        }
        // 1個寫線程(獨占,所有讀線程等待)
        new Thread(() -> updateCache(100), "寫線程").start();
    }
}

5. synchronized 的鎖升級(偏向鎖→輕量級鎖→重量級鎖)

JDK1.6 為優(yōu)化 synchronized 引入的自適應鎖機制,鎖級別從低到高升級(不可逆),適配不同并發(fā)場景:

鎖類型核心特點適用場景
偏向鎖鎖偏向第一個線程,無競爭時零開銷單線程執(zhí)行同步代碼(如初始化資源)
輕量級鎖多線程交替競爭,CAS 自旋獲取鎖少量線程(2-3 個)交替執(zhí)行
重量級鎖多線程激烈競爭,線程阻塞(OS 層面)大量線程同時競爭鎖

6. 自旋鎖 vs 阻塞鎖

類型定義示例適用場景
自旋鎖獲取鎖失敗時循環(huán)重試(自旋),不阻塞CAS、synchronized 輕量級鎖鎖持有時間短、低沖突(如簡單變量更新)
阻塞鎖獲取鎖失敗時線程阻塞,釋放 CPUsynchronized 重量級鎖、ReentrantLock鎖持有時間長、高沖突(如復雜業(yè)務邏輯)

7. 分段鎖(ConcurrentHashMap JDK1.7)

核心定義

將數(shù)據(jù)拆分為多個「段(Segment)」,每個段獨立加鎖,不同段的操作互不阻塞,并發(fā)度 = 段數(shù)(默認 16)。

適用場景

JDK1.7 的 ConcurrentHashMap(JDK1.8 后用 CAS+Synchronized 替代),適用于高并發(fā)讀寫 Map 的場景。

三、實戰(zhàn)選型指南(核心)

業(yè)務場景推薦鎖類型選型原因
簡單互斥、代碼簡潔synchronized隱式鎖,無需手動釋放,JVM 優(yōu)化優(yōu)異
可中斷 / 超時 / 公平鎖ReentrantLock支持靈活的鎖控制特性
讀多寫少(緩存 / 查詢)ReentrantReadWriteLock/StampedLock讀共享,大幅提升讀并發(fā)效率
低沖突、簡單變量更新CAS(AtomicInteger/AtomicLong)無鎖,性能最高,避免自旋消耗
高沖突、寫多讀少(轉(zhuǎn)賬)synchronized/ReentrantLock悲觀鎖,避免高沖突下的 CAS 自旋 CPU 開銷
公平性要求高(任務排隊)ReentrantLock(true)按請求順序獲取鎖,避免線程饑餓
高并發(fā) Map 操作ConcurrentHashMapJDK1.8 用 CAS+Synchronized,兼顧性能和安全性

總結(jié)

關鍵點回顧

  1. 基礎核心:synchronized(簡單、通用)和 Lock 接口(靈活、高級)是 Java 鎖的兩大基石,前者適用于普通場景,后者適用于需要靈活控制的場景;
  2. 特性選型:讀多寫少選讀寫鎖,低沖突選樂觀鎖 / CAS,高沖突選悲觀鎖,公平性要求高選公平鎖;
  3. 性能原則:優(yōu)先選擇「開銷低」的鎖(如偏向鎖、CAS),高沖突場景才用「高開銷」的阻塞鎖(如重量級鎖);
  4. 實戰(zhàn)建議:90% 的普通業(yè)務場景用 synchronized 即可,僅在需要可中斷、超時、讀寫分離時才用 Lock 接口實現(xiàn)類。

到此這篇關于Java中鎖分類及在什么場景下使用的文章就介紹到這了,更多相關java鎖使用內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • 教你1秒將本地SpringBoot項目jar包部署到Linux環(huán)境(超詳細!)

    教你1秒將本地SpringBoot項目jar包部署到Linux環(huán)境(超詳細!)

    spring Boot簡化了Spring應用的開發(fā)過程,遵循約定優(yōu)先配置的原則提供了各類開箱即用(out-of-the-box)的框架配置,下面這篇文章主要給大家介紹了關于1秒將本地SpringBoot項目jar包部署到Linux環(huán)境的相關資料,超級詳細,需要的朋友可以參考下
    2023-04-04
  • java socket長連接中解決read阻塞的3個辦法

    java socket長連接中解決read阻塞的3個辦法

    這篇文章主要介紹了java socket長連接中解決read阻塞的3個辦法,本文取了折中的一個方法,并給出代碼實例,需要的朋友可以參考下
    2014-08-08
  • @DS注解的使用,動態(tài)數(shù)據(jù)源,事務詳解

    @DS注解的使用,動態(tài)數(shù)據(jù)源,事務詳解

    在項目中使用多數(shù)據(jù)源時,可以借助苞米豆的dynamic-datasource-spring-boot-starter進行配置,首先需引入相應的jar包,并在application.yml中設置主從數(shù)據(jù)源,其中一般選擇master作為默認數(shù)據(jù)源,在實現(xiàn)類中通過@DS注解指定數(shù)據(jù)源
    2024-09-09
  • Java你不了解的大數(shù)型BigInteger與BigDecimal類

    Java你不了解的大數(shù)型BigInteger與BigDecimal類

    這篇文章主要介紹了Java 處理超大數(shù)類型之BigInteger與BigDecimal案例詳解,本篇文章通過簡要的案例,講解了該項技術的了解與使用,以下就是詳細內(nèi)容,需要的朋友可以參考下
    2022-05-05
  • Java鏈表的天然遞歸結(jié)構性質(zhì)圖文與實例分析

    Java鏈表的天然遞歸結(jié)構性質(zhì)圖文與實例分析

    這篇文章主要介紹了Java鏈表的天然遞歸結(jié)構性質(zhì),結(jié)合圖文與實例形式分析了java鏈表中遞歸操作的原理、實現(xiàn)技巧與相關注意事項,需要的朋友可以參考下
    2020-03-03
  • Spring Security注冊過濾器注意事項詳解

    Spring Security注冊過濾器注意事項詳解

    前兩天和小伙伴聊了 Spring Security+JWT 實現(xiàn)無狀態(tài)登錄,然后有小伙伴反饋了一個問題,感覺這是一個我們平時寫代碼容易忽略的問題,所以本文給大家介紹了Spring Security注冊過濾器注意事項,需要的朋友可以參考下
    2024-06-06
  • 使用spring oauth2框架獲取當前登錄用戶信息的實現(xiàn)代碼

    使用spring oauth2框架獲取當前登錄用戶信息的實現(xiàn)代碼

    這篇文章主要介紹了使用spring oauth2框架獲取當前登錄用戶信息的實現(xiàn)代碼,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-07-07
  • Java構造器與傳值學習總結(jié)

    Java構造器與傳值學習總結(jié)

    這篇文章主要為大家詳細介紹了Java構造器與傳值學習總結(jié),文中示例介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-01-01
  • java servlet 幾種頁面跳轉(zhuǎn)的方法

    java servlet 幾種頁面跳轉(zhuǎn)的方法

    java servlet 幾種頁面跳轉(zhuǎn)的方法,需要的朋友可以參考一下
    2013-04-04
  • Spring如何重寫內(nèi)置Bean(Controller、Service等)

    Spring如何重寫內(nèi)置Bean(Controller、Service等)

    本文介紹了在Spring Boot工程中處理外部JAR包中Controller方法重寫的需求,通過PostProcessor方式和自定義注解@ExcludeBean兩種方法,解決了在不修改源代碼的情況下重寫接口的問題
    2025-01-01

最新評論

宁都县| 阳西县| 横峰县| 府谷县| 定州市| 贵州省| 余庆县| 绥江县| 宣汉县| 屏山县| 云阳县| 秭归县| 若尔盖县| 屯门区| 娱乐| 扬中市| 磴口县| 寻甸| 富阳市| 基隆市| 名山县| 松滋市| 十堰市| 会同县| 保靖县| 桐城市| 达尔| 禹州市| 南靖县| 嘉峪关市| 栖霞市| 河西区| 江西省| 灌阳县| 井冈山市| 商南县| 巴彦县| 平原县| 津南区| 涡阳县| 怀化市|