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

Java重入鎖(ReentrantLock)從入門到源碼深度解析

 更新時間:2026年02月26日 16:11:06   作者:百錦再@新空間創(chuàng)想科技  
本文給大家介紹Java重入鎖(ReentrantLock)從入門到源碼深度解析,通過本文學(xué)習(xí)可以全方位地認(rèn)識ReentrantLock,從基本概念到高級特性,從使用方式到源碼剖析,從底層原理到實(shí)際應(yīng)用,感興趣的朋友跟隨小編一起看看吧

引言

在多線程編程的世界里,鎖是最核心的同步工具之一。Java從語言層面提供了synchronized關(guān)鍵字來實(shí)現(xiàn)線程同步,簡單而有效。然而,隨著并發(fā)需求的復(fù)雜化,synchronized的局限性逐漸顯現(xiàn)——它無法響應(yīng)中斷、無法設(shè)置超時、默認(rèn)非公平且靈活性不足。為了解決這些問題,Java在java.util.concurrent.locks包中提供了ReentrantLock(重入鎖),一個功能更強(qiáng)大、使用更靈活的鎖工具。

本文將帶你全方位地認(rèn)識ReentrantLock,從基本概念到高級特性,從使用方式到源碼剖析,從底層原理到實(shí)際應(yīng)用。無論你是初學(xué)者還是希望深入理解并發(fā)編程的開發(fā)者,相信都能從中獲得啟發(fā)。全文約8500字,建議結(jié)合實(shí)踐閱讀。

第一部分:重入鎖基礎(chǔ)概念

1.1 什么是重入鎖?

重入鎖(Reentrant Lock),顧名思義,就是支持重入特性的鎖。重入是指:同一個線程在持有鎖的情況下,可以多次獲取同一把鎖而不會被阻塞

舉個例子:如果一個線程已經(jīng)獲得了某個對象的鎖,當(dāng)它再次請求該對象的鎖時,會直接成功,而不是死鎖等待。這種機(jī)制在遞歸方法調(diào)用或嵌套同步塊中至關(guān)重要。

public class ReentrantExample {
    private final Object lock = new Object();
    public void methodA() {
        synchronized (lock) {
            // 已經(jīng)持有鎖
            methodB(); // 再次請求同一把鎖
        }
    }
    public void methodB() {
        synchronized (lock) {
            // 這里不會死鎖,因為synchronized是可重入的
            System.out.println("methodB執(zhí)行");
        }
    }
}

ReentrantLock同樣支持這種重入特性,但它提供了比synchronized更豐富的功能。

1.2 為什么需要重入鎖?

synchronized作為Java內(nèi)置的關(guān)鍵字,使用簡單,由JVM自動加鎖和解鎖,且經(jīng)過多年的優(yōu)化(偏向鎖、輕量級鎖、重量級鎖升級),性能已經(jīng)不遜色于ReentrantLock。既然如此,為什么還需要ReentrantLock?

這是因為ReentrantLock彌補(bǔ)了synchronized的幾個功能性缺陷

特性synchronizedReentrantLock
使用方式關(guān)鍵字,自動釋放API調(diào)用,需手動釋放
鎖獲取響應(yīng)中斷不支持支持(lockInterruptibly()
嘗試獲取鎖不支持支持(tryLock()
超時獲取鎖不支持支持(tryLock(long, TimeUnit)
公平鎖非公平可設(shè)置公平/非公平
條件變量每個對象一個等待集一個鎖可綁定多個Condition
獲取鎖狀態(tài)無法得知可查詢持有線程、等待隊列等

簡單來說,當(dāng)需要更精細(xì)的控制同步行為時,ReentrantLock是更好的選擇。

1.3 ReentrantLock的基本用法

在深入原理之前,我們先來看看ReentrantLock的標(biāo)準(zhǔn)使用模式:

import java.util.concurrent.locks.ReentrantLock;
public class Counter {
    private final ReentrantLock lock = new ReentrantLock();
    private int count = 0;
    public void increment() {
        lock.lock(); // 獲取鎖
        try {
            count++;
        } finally {
            lock.unlock(); // 必須在finally中釋放鎖!
        }
    }
    public int getCount() {
        lock.lock();
        try {
            return count;
        } finally {
            lock.unlock();
        }
    }
}

核心要點(diǎn)

  • lock()unlock()必須成對出現(xiàn)
  • 解鎖操作必須放在finally塊中,確保無論是否發(fā)生異常都能釋放鎖
  • 不能在try塊中調(diào)用lock(),因為lock()本身可能拋出異常

第二部分:ReentrantLock的核心特性

2.1 可重入性

可重入性是ReentrantLock命名中的核心特性。它通過計數(shù)機(jī)制實(shí)現(xiàn):

public class ReentrantDemo {
    private final ReentrantLock lock = new ReentrantLock();
    public void outer() {
        lock.lock();
        try {
            System.out.println("外層方法獲取鎖");
            inner();
        } finally {
            lock.unlock();
        }
    }
    public void inner() {
        lock.lock(); // 同一線程再次獲取鎖
        try {
            System.out.println("內(nèi)層方法再次獲取鎖");
        } finally {
            lock.unlock();
        }
    }
}

內(nèi)部原理:每個鎖關(guān)聯(lián)一個持有線程和一個計數(shù)器。當(dāng)線程第一次獲取鎖時,計數(shù)器置為1;同一個線程再次獲取鎖時,計數(shù)器遞增;每釋放一次,計數(shù)器遞減;當(dāng)計數(shù)器歸零時,鎖完全釋放,其他線程才能獲取。

2.2 公平鎖與非公平鎖

2.2.1 概念解析

  • 公平鎖(FairSync):線程按照請求鎖的先后順序(FIFO)獲取鎖,不會產(chǎn)生饑餓現(xiàn)象。
  • 非公平鎖(NonfairSync):線程在獲取鎖時,允許"插隊",即直接嘗試搶占鎖,如果搶占成功就直接獲得鎖,搶占失敗才進(jìn)入隊列等待。

ReentrantLock默認(rèn)使用非公平鎖,但可以通過構(gòu)造器參數(shù)設(shè)置為公平鎖:

ReentrantLock fairLock = new ReentrantLock(true);   // 公平鎖
ReentrantLock unfairLock = new ReentrantLock(false); // 非公平鎖
ReentrantLock defaultLock = new ReentrantLock();    // 默認(rèn)非公平鎖

2.2.2 為什么默認(rèn)非公平鎖?

非公平鎖雖然可能導(dǎo)致線程饑餓,但性能更高。原因在于:

  • 公平鎖需要維護(hù)嚴(yán)格的排隊機(jī)制,線程喚醒有開銷
  • 非公平鎖減少了線程的掛起和喚醒次數(shù)
  • 在高并發(fā)場景下,非公平鎖的吞吐量通常優(yōu)于公平鎖

2.2.3 源碼層面的差異

我們來看看非公平鎖的lock()方法:

// NonfairSync的lock方法
final void lock() {
    // 直接嘗試搶占鎖(插隊)
    if (compareAndSetState(0, 1))
        setExclusiveOwnerThread(Thread.currentThread());
    else
        acquire(1);
}

而公平鎖的lock()方法:

// FairSync的lock方法
final void lock() {
    acquire(1); // 直接進(jìn)入隊列,沒有搶占機(jī)會
}

公平鎖的tryAcquire方法中多了一個關(guān)鍵判斷:

protected final boolean tryAcquire(int acquires) {
    final Thread current = Thread.currentThread();
    int c = getState();
    if (c == 0) {
        // 公平鎖的額外判斷:隊列中是否有前驅(qū)節(jié)點(diǎn)
        if (!hasQueuedPredecessors() && 
            compareAndSetState(0, acquires)) {
            setExclusiveOwnerThread(current);
            return true;
        }
    }
    // ... 重入邏輯
    return false;
}

hasQueuedPredecessors()檢查隊列中是否有等待時間更長的線程,確保嚴(yán)格FIFO。

2.3 可中斷鎖

synchronized在等待鎖的過程中無法響應(yīng)中斷,而ReentrantLock提供了可中斷的獲取鎖方式:

public class InterruptibleDemo {
    private final ReentrantLock lock = new ReentrantLock();
    public void performTask() throws InterruptedException {
        // 可響應(yīng)中斷的鎖獲取
        lock.lockInterruptibly();
        try {
            // 執(zhí)行需要同步的操作
            System.out.println(Thread.currentThread().getName() + " 獲得鎖");
            Thread.sleep(5000);
        } finally {
            lock.unlock();
        }
    }
    public static void main(String[] args) throws Exception {
        InterruptibleDemo demo = new InterruptibleDemo();
        Thread t1 = new Thread(() -> {
            try {
                demo.performTask();
            } catch (InterruptedException e) {
                System.out.println("線程1被中斷");
            }
        });
        Thread t2 = new Thread(() -> {
            try {
                demo.performTask();
            } catch (InterruptedException e) {
                System.out.println("線程2被中斷");
            }
        });
        t1.start();
        Thread.sleep(100); // 確保t1先獲得鎖
        t2.start();
        // 中斷正在等待鎖的t2
        t2.interrupt();
    }
}

當(dāng)t2在等待鎖時被中斷,會立即拋出InterruptedException,從而有機(jī)會響應(yīng)中斷,而不是無限阻塞。

2.4 限時等待鎖

在實(shí)際開發(fā)中,無限等待鎖可能導(dǎo)致系統(tǒng)死鎖或響應(yīng)延遲。ReentrantLock提供了帶超時的鎖獲取方法:

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;
public class TimeoutDemo {
    private final ReentrantLock lock = new ReentrantLock();
    public boolean tryExecute() {
        try {
            // 嘗試在3秒內(nèi)獲取鎖
            if (lock.tryLock(3, TimeUnit.SECONDS)) {
                try {
                    System.out.println(Thread.currentThread().getName() + " 獲得鎖");
                    Thread.sleep(2000); // 模擬業(yè)務(wù)操作
                    return true;
                } finally {
                    lock.unlock();
                }
            } else {
                System.out.println(Thread.currentThread().getName() + " 獲取鎖超時");
                return false;
            }
        } catch (InterruptedException e) {
            System.out.println("線程被中斷");
            return false;
        }
    }
}

tryLock()還有無參版本:如果鎖可用則立即獲取,否則立即返回false,不會阻塞。

2.5 條件變量(Condition)

ConditionObjectwait()、notify()、notifyAll()方法分解為不同的條件對象,使得一個鎖可以支持多個等待集,實(shí)現(xiàn)更精細(xì)的線程協(xié)作。

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
public class BoundedBuffer {
    private final ReentrantLock lock = new ReentrantLock();
    private final Condition notFull = lock.newCondition();
    private final Condition notEmpty = lock.newCondition();
    private final Object[] items = new Object[10];
    private int putIndex, takeIndex, count;
    public void put(Object x) throws InterruptedException {
        lock.lock();
        try {
            // 當(dāng)隊列滿時,等待notFull條件
            while (count == items.length) {
                notFull.await(); // 釋放鎖,進(jìn)入等待
            }
            items[putIndex] = x;
            if (++putIndex == items.length) putIndex = 0;
            count++;
            // 通知等待notEmpty條件的線程
            notEmpty.signal();
        } finally {
            lock.unlock();
        }
    }
    public Object take() throws InterruptedException {
        lock.lock();
        try {
            // 當(dāng)隊列空時,等待notEmpty條件
            while (count == 0) {
                notEmpty.await();
            }
            Object x = items[takeIndex];
            if (++takeIndex == items.length) takeIndex = 0;
            count--;
            // 通知等待notFull條件的線程
            notFull.signal();
            return x;
        } finally {
            lock.unlock();
        }
    }
}

優(yōu)勢:與synchronized相比,Condition可以創(chuàng)建多個等待集,更靈活地控制線程協(xié)作。

第三部分:ReentrantLock與synchronized的全面對比

3.1 異同點(diǎn)總結(jié)

比較維度synchronizedReentrantLock
實(shí)現(xiàn)方式JVM內(nèi)置關(guān)鍵字Java API實(shí)現(xiàn),基于AQS
鎖釋放自動釋放(退出同步塊)手動釋放(需finally中unlock)
可重入性支持支持
公平性非公平可公平可非公平
響應(yīng)中斷不支持支持(lockInterruptibly)
超時獲取不支持支持(tryLock帶超時)
嘗試獲取不支持支持(tryLock無參)
條件變量每個對象一個等待集一個鎖可多個Condition
鎖狀態(tài)查詢無法查詢可查詢持有線程、等待隊列長度等
性能JDK6后優(yōu)化良好高競爭場景表現(xiàn)更優(yōu)

3.2 如何選擇?

根據(jù)實(shí)際場景選擇:

  • 優(yōu)先使用synchronized:當(dāng)同步邏輯簡單、不需要高級特性時。它簡潔、不易出錯,且JVM持續(xù)優(yōu)化。
  • 需要公平鎖:必須保證線程獲取鎖的順序時。
  • 需要可中斷鎖:希望避免線程無限期阻塞時。
  • 需要超時獲取鎖:防止死鎖或保證響應(yīng)時間時。
  • 需要多個條件變量:生產(chǎn)者-消費(fèi)者模式等復(fù)雜協(xié)作時。
  • 高競爭場景ReentrantLock在高并發(fā)下表現(xiàn)更好。

第四部分:ReentrantLock源碼深度剖析

4.1 AQS基礎(chǔ):重入鎖的基石

要理解ReentrantLock,必須先理解AQS(AbstractQueuedSynchronizer)。AQS是Java并發(fā)包的基石,ReentrantLock、Semaphore、CountDownLatch等工具都基于它實(shí)現(xiàn)。

4.1.1 AQS的核心思想

AQS維護(hù)了兩個核心元素:

  1. volatile int state:同步狀態(tài),對于ReentrantLock,state表示鎖的持有次數(shù)(0表示未持有,≥1表示持有次數(shù))。
  2. FIFO等待隊列(CLH隊列變體):用于存放獲取鎖失敗的線程。

核心操作:通過CAS(Compare And Swap)原子性地修改state值,成功則獲得鎖,失敗則進(jìn)入等待隊列。

4.1.2 AQS的關(guān)鍵方法

方法描述
tryAcquire(int arg)嘗試獲取鎖,由子類實(shí)現(xiàn)
tryRelease(int arg)嘗試釋放鎖,由子類實(shí)現(xiàn)
acquire(int arg)獲取鎖的模板方法
release(int arg)釋放鎖的模板方法

ReentrantLock內(nèi)部類Sync繼承AQS,并實(shí)現(xiàn)了tryAcquiretryRelease

4.2 非公平鎖源碼解析

4.2.1 加鎖過程

// ReentrantLock.NonfairSync
final void lock() {
    // 第一步:直接嘗試搶占鎖(插隊)
    if (compareAndSetState(0, 1))
        setExclusiveOwnerThread(Thread.currentThread());
    else
        acquire(1); // 搶占失敗,進(jìn)入AQS流程
}
  • compareAndSetState(0, 1):通過CAS嘗試將state從0改為1。如果成功,表示當(dāng)前線程直接搶到了鎖,設(shè)置獨(dú)占線程為當(dāng)前線程。
  • 如果CAS失敗(鎖已被其他線程持有),調(diào)用acquire(1)進(jìn)入AQS的獲取流程。
// AbstractQueuedSynchronizer.acquire
public final void acquire(int arg) {
    if (!tryAcquire(arg) &&          // 再次嘗試獲?。ǚ枪桨妫?
        acquireQueued(addWaiter(Node.EXCLUSIVE), arg)) // 加入等待隊列
        selfInterrupt();
}

這里的tryAcquire調(diào)用的是NonfairSync實(shí)現(xiàn)的nonfairTryAcquire

final boolean nonfairTryAcquire(int acquires) {
    final Thread current = Thread.currentThread();
    int c = getState();
    if (c == 0) {
        // state為0,說明鎖空閑,再次嘗試CAS搶占
        if (compareAndSetState(0, acquires)) {
            setExclusiveOwnerThread(current);
            return true;
        }
    }
    else if (current == getExclusiveOwnerThread()) {
        // 重入:同一線程再次獲取鎖
        int nextc = c + acquires;
        if (nextc < 0) // overflow
            throw new Error("Maximum lock count exceeded");
        setState(nextc);
        return true;
    }
    return false;
}

非公平的體現(xiàn):即使線程已經(jīng)進(jìn)入等待隊列,在tryAcquire階段仍然會嘗試CAS搶占,而不是嚴(yán)格排隊。

4.2.2 入隊等待

如果tryAcquire失敗,則執(zhí)行addWaiter將當(dāng)前線程封裝成Node加入等待隊列尾部:

private Node addWaiter(Node mode) {
    Node node = new Node(Thread.currentThread(), mode);
    Node pred = tail;
    if (pred != null) {
        node.prev = pred;
        if (compareAndSetTail(pred, node)) {
            pred.next = node;
            return node;
        }
    }
    enq(node); // 入隊失敗或有并發(fā)時,通過自旋CAS入隊
    return node;
}

然后執(zhí)行acquireQueued,在隊列中自旋等待:

final boolean acquireQueued(final Node node, int arg) {
    boolean failed = true;
    try {
        boolean interrupted = false;
        for (;;) {
            final Node p = node.predecessor();
            // 如果前驅(qū)是頭節(jié)點(diǎn),再次嘗試獲取鎖
            if (p == head && tryAcquire(arg)) {
                setHead(node);
                p.next = null; // help GC
                failed = false;
                return interrupted;
            }
            // 檢查是否需要掛起線程
            if (shouldParkAfterFailedAcquire(p, node) &&
                parkAndCheckInterrupt())
                interrupted = true;
        }
    } finally {
        if (failed)
            cancelAcquire(node);
    }
}

當(dāng)線程獲取鎖失敗時,會被park(掛起),等待前驅(qū)線程釋放鎖時unpark喚醒。

4.2.3 釋放鎖

// ReentrantLock.Sync
protected final boolean tryRelease(int releases) {
    int c = getState() - releases;
    if (Thread.currentThread() != getExclusiveOwnerThread())
        throw new IllegalMonitorStateException();
    boolean free = false;
    if (c == 0) {
        free = true;
        setExclusiveOwnerThread(null);
    }
    setState(c);
    return free;
}

釋放鎖時遞減state,直到state歸零才真正釋放鎖。然后AQS會喚醒隊列中的下一個節(jié)點(diǎn)。

4.3 公平鎖源碼解析

公平鎖的lock()方法直接調(diào)用acquire(1),沒有搶占嘗試:

// FairSync.lock
final void lock() {
    acquire(1);
}

公平鎖的tryAcquire與非公平鎖的核心區(qū)別在于多了hasQueuedPredecessors()判斷:

protected final boolean tryAcquire(int acquires) {
    final Thread current = Thread.currentThread();
    int c = getState();
    if (c == 0) {
        // 公平鎖:檢查隊列中是否有前驅(qū)節(jié)點(diǎn)
        if (!hasQueuedPredecessors() && 
            compareAndSetState(0, acquires)) {
            setExclusiveOwnerThread(current);
            return true;
        }
    }
    // ... 重入邏輯
    return false;
}

hasQueuedPredecessors()判斷當(dāng)前線程之前是否有等待的線程,確保FIFO順序。

4.4 限時獲取鎖的實(shí)現(xiàn)

tryLock(long timeout, TimeUnit unit)的底層通過doAcquireNanos實(shí)現(xiàn):

private boolean doAcquireNanos(int arg, long nanosTimeout)
        throws InterruptedException {
    long lastTime = System.nanoTime();
    final Node node = addWaiter(Node.EXCLUSIVE);
    // ...
    for (;;) {
        // 嘗試獲取鎖
        // 計算剩余時間,超時則返回false
        nanosTimeout -= System.nanoTime() - lastTime;
        if (nanosTimeout <= 0) {
            cancelAcquire(node);
            return false;
        }
        // 如果超時時間短,自旋;否則掛起
        if (shouldParkAfterFailedAcquire(p, node) &&
            nanosTimeout > spinForTimeoutThreshold)
            LockSupport.parkNanos(this, nanosTimeout);
        // ...
    }
}

通過LockSupport.parkNanos實(shí)現(xiàn)限時阻塞,超時后自動喚醒并返回失敗。

第五部分:CAS與AQS——重入鎖的底層基石

5.1 CAS操作

CAS(Compare And Swap)是并發(fā)編程中實(shí)現(xiàn)無鎖算法的核心技術(shù)。它是一條CPU原子指令,包含三個操作數(shù):

  • 內(nèi)存地址V
  • 期望值A(chǔ)
  • 新值B

僅當(dāng)V的值等于A時,才將V更新為B,整個過程原子完成。

在Java中,Unsafe類提供了CAS操作,ReentrantLock通過CAS修改AQS的state字段。

5.2 CAS的ABA問題

ABA問題:線程1讀取變量值為A,此時線程2將A改為B再改回A,線程1CAS時發(fā)現(xiàn)仍是A,于是更新成功。但實(shí)際上變量已經(jīng)被修改過。

解決方案:使用版本號或時間戳。Java提供了AtomicStampedReference來解決ABA問題。

5.3 AQS的設(shè)計精髓

AQS的核心設(shè)計理念包括:

  1. 模板方法模式:定義獲取/釋放鎖的骨架,具體實(shí)現(xiàn)由子類完成。
  2. CLH隊列變體:高效的雙向隊列管理等待線程。
  3. 狀態(tài)依賴:通過state表示同步狀態(tài)。
  4. 自旋與阻塞結(jié)合:短時間內(nèi)自旋,長時間阻塞,平衡性能。
  5. LockSupport:提供線程掛起和喚醒的底層支持。

第六部分:實(shí)戰(zhàn)應(yīng)用與最佳實(shí)踐

6.1 標(biāo)準(zhǔn)使用模板

public class SafeCounter {
    private final ReentrantLock lock = new ReentrantLock();
    private int count = 0;
    public void increment() {
        lock.lock();
        try {
            count++;
        } finally {
            lock.unlock();
        }
    }
    // 帶超時的獲取
    public boolean tryIncrement(long timeout, TimeUnit unit) {
        try {
            if (lock.tryLock(timeout, unit)) {
                try {
                    count++;
                    return true;
                } finally {
                    lock.unlock();
                }
            }
            return false;
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            return false;
        }
    }
}

6.2 監(jiān)控與調(diào)試

ReentrantLock提供了監(jiān)控鎖狀態(tài)的方法:

ReentrantLock lock = new ReentrantLock();
// 查詢鎖狀態(tài)
System.out.println("鎖持有線程: " + lock.getOwner());
System.out.println("等待線程數(shù): " + lock.getQueueLength());
System.out.println("是否被當(dāng)前線程持有: " + lock.isHeldByCurrentThread());
System.out.println("是否公平鎖: " + lock.isFair());

這些方法對調(diào)試死鎖、監(jiān)控系統(tǒng)狀態(tài)非常有幫助。

6.3 常見陷阱與注意事項

  1. 忘記釋放鎖:必須在finally中unlock。
  2. 在try塊內(nèi)lock:lock()可能拋出異常,應(yīng)該先lock再try。
  3. 鎖的可見性問題:ReentrantLock保證內(nèi)存可見性,無需額外volatile。
  4. 重入計數(shù)溢出:重入次數(shù)受int范圍限制,理論上可達(dá)21億次。
  5. 與synchronized混用:不同鎖機(jī)制之間不互斥,需注意設(shè)計。

6.4 性能考量

  • 低競爭場景:synchronized性能略優(yōu)或持平
  • 高競爭場景:ReentrantLock性能更好
  • 公平鎖性能低于非公平鎖
  • 避免在鎖內(nèi)執(zhí)行耗時操作

結(jié)語

ReentrantLock作為Java并發(fā)包中的核心工具,以其強(qiáng)大的功能和靈活的機(jī)制,成為高并發(fā)編程中不可或缺的利器。通過本文的學(xué)習(xí),我們深入理解了:

  • 可重入性的實(shí)現(xiàn)原理
  • 公平鎖與非公平鎖的源碼差異
  • 可中斷、限時等待等高級特性
  • AQS作為底層的核心架構(gòu)
  • 最佳實(shí)踐與性能考量

掌握ReentrantLock不僅僅是學(xué)會使用一個類,更是理解Java并發(fā)編程思想的重要一步。在實(shí)際開發(fā)中,根據(jù)場景選擇合適的同步工具,平衡功能與性能,才能寫出高質(zhì)量的多線程程序。

到此這篇關(guān)于Java重入鎖(ReentrantLock)全面解析:從入門到源碼深度剖析的文章就介紹到這了,更多相關(guān)Java重入鎖ReentrantLock內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 淺談SpringBoot之事務(wù)處理機(jī)制

    淺談SpringBoot之事務(wù)處理機(jī)制

    這篇文章主要介紹了淺談SpringBoot之事務(wù)處理機(jī)制,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-01-01
  • 搭建MyBatis開發(fā)環(huán)境及基本的CURD介紹

    搭建MyBatis開發(fā)環(huán)境及基本的CURD介紹

    這篇文章主要介紹了搭建MyBatis開發(fā)環(huán)境及基本的CURD,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-08-08
  • Java的HashSet源碼詳解

    Java的HashSet源碼詳解

    這篇文章主要介紹了Java的HashSet源碼詳解,HashSet底層封裝的是HashMap,所以元素添加會放到HashMap的key中,value值使用new Object對象作為value,所以HashSet和HashMap的所具有的特點(diǎn)是類似的,需要的朋友可以參考下
    2023-09-09
  • springboot 2.3之后消失的hibernate-validator解決方法

    springboot 2.3之后消失的hibernate-validator解決方法

    這篇文章主要介紹了springboot 2.3之后消失的hibernate-validator解決方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-08-08
  • Mybatis Plus Wrapper查詢某幾列的方法實(shí)現(xiàn)

    Mybatis Plus Wrapper查詢某幾列的方法實(shí)現(xiàn)

    MybatisPlus中,使用Wrapper的select和notSelect方法可以精確控制查詢的字段,本文就來介紹一下Mybatis Plus Wrapper查詢某幾列的方法實(shí)現(xiàn),感興趣的可以了解一下
    2024-10-10
  • 使用IntelliJ IDEA調(diào)式Stream流的方法步驟

    使用IntelliJ IDEA調(diào)式Stream流的方法步驟

    本文主要介紹了使用IntelliJ IDEA調(diào)式Stream流的方法步驟,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-05-05
  • Java字符串拼接詳解

    Java字符串拼接詳解

    大家好,本篇文章主要講的是Java字符串拼接詳解,感興趣的同學(xué)趕快來看一看吧,對你有幫助的話記得收藏一下
    2022-02-02
  • spring?cloud?eureka注冊原理-注冊失敗填坑筆記

    spring?cloud?eureka注冊原理-注冊失敗填坑筆記

    這篇文章主要介紹了spring?cloud?eureka注冊原理-注冊失敗填坑筆記,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-05-05
  • 將一個數(shù)組按照固定大小進(jìn)行拆分成數(shù)組的方法

    將一個數(shù)組按照固定大小進(jìn)行拆分成數(shù)組的方法

    下面小編就為大家?guī)硪黄獙⒁粋€數(shù)組按照固定大小進(jìn)行拆分成數(shù)組的方法。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-11-11
  • SpringBoot內(nèi)嵌tomcat處理有特殊字符轉(zhuǎn)義的問題

    SpringBoot內(nèi)嵌tomcat處理有特殊字符轉(zhuǎn)義的問題

    這篇文章主要介紹了SpringBoot內(nèi)嵌tomcat處理有特殊字符轉(zhuǎn)義的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-06-06

最新評論

抚松县| 务川| 汕尾市| 五家渠市| 济阳县| 宜兴市| 道真| 碌曲县| 磐石市| 淮南市| 万安县| 边坝县| 岢岚县| 郯城县| 碌曲县| 平乡县| 临清市| 乐山市| 宁强县| 松潘县| 六盘水市| 依安县| 秦皇岛市| 上高县| 天津市| 陈巴尔虎旗| 眉山市| 鹤壁市| 旺苍县| 胶州市| 丰镇市| 沐川县| 苏尼特左旗| 霞浦县| 东至县| 武功县| 扶沟县| 鲜城| 太保市| 永登县| 万荣县|