Java并發(fā)編程之ReentrantLock的實現(xiàn)示例
一、可中斷鎖
1. 核心方法:lockInterruptibly()
- 作用:允許線程在等待鎖的過程中響應中斷請求。
- 適用場景:需要支持任務取消或中斷的同步操作(如用戶手動取消長時間等待的任務)。
2. 代碼示例
ReentrantLock lock = new ReentrantLock();
Thread thread = new Thread(() -> {
try {
lock.lockInterruptibly(); // 可中斷獲取鎖
try {
System.out.println("線程獲取鎖并執(zhí)行任務");
Thread.sleep(5000); // 模擬耗時操作
} finally {
lock.unlock();
}
} catch (InterruptedException e) {
System.out.println("線程被中斷,放棄獲取鎖");
}
});
lock.lock(); // 主線程先獲取鎖
try {
thread.start();
Thread.sleep(1000); // 確保子線程開始等待鎖
thread.interrupt(); // 中斷子線程
} finally {
lock.unlock();
}
3. 行為分析
- 未中斷時:線程正常獲取鎖并執(zhí)行任務。
- 中斷時:拋出
InterruptedException,線程退出等待隊列。
二、鎖超時
1. 核心方法:tryLock()
無參方法:
boolean tryLock()
立即嘗試獲取鎖,成功返回true,失敗返回false。帶超時方法:
boolean tryLock(long timeout, TimeUnit unit)
在指定時間內(nèi)嘗試獲取鎖,超時后放棄。
2. 代碼示例:避免死鎖
ReentrantLock lockA = new ReentrantLock();
ReentrantLock lockB = new ReentrantLock();
Thread thread1 = new Thread(() -> {
try {
if (lockA.tryLock(1, TimeUnit.SECONDS)) { // 嘗試獲取lockA
try {
if (lockB.tryLock(1, TimeUnit.SECONDS)) { // 嘗試獲取lockB
System.out.println("Thread1完成任務");
}
} finally {
if (lockB.isHeldByCurrentThread()) lockB.unlock();
}
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
if (lockA.isHeldByCurrentThread()) lockA.unlock();
}
});
Thread thread2 = new Thread(() -> { /* 類似邏輯,先嘗試lockB再lockA */ });
thread1.start();
thread2.start();
3. 應用場景
- 死鎖預防:通過超時放棄鎖請求,打破循環(huán)等待。
- 響應性優(yōu)化:避免線程長時間阻塞影響系統(tǒng)響應速度。
三、條件變量
1. 核心機制
- 創(chuàng)建條件變量:
Condition condition = lock.newCondition(); - 等待條件:
condition.await(); - 喚醒線程:
condition.signal()或condition.signalAll()
2. 代碼示例:生產(chǎn)者-消費者模型
ReentrantLock lock = new ReentrantLock();
Condition notEmpty = lock.newCondition(); // 非空條件
Condition notFull = lock.newCondition(); // 非滿條件
Queue<Integer> queue = new LinkedList<>();
int maxSize = 10;
// 生產(chǎn)者
new Thread(() -> {
lock.lock();
try {
while (queue.size() == maxSize) {
notFull.await(); // 等待隊列非滿
}
queue.add(1);
notEmpty.signal(); // 通知消費者
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}).start();
// 消費者
new Thread(() -> {
lock.lock();
try {
while (queue.isEmpty()) {
notEmpty.await(); // 等待隊列非空
}
queue.poll();
notFull.signal(); // 通知生產(chǎn)者
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}).start();
3. 優(yōu)勢對比wait()/notify()
| 特性 | Condition | wait()/notify() |
|---|---|---|
| 多條件支持 | ? 可創(chuàng)建多個條件變量 | ? 每個對象僅一個等待隊列 |
| 精準喚醒 | ? signal() 喚醒指定條件隊列的線程 | ? notify() 隨機喚醒 |
四、關鍵注意事項
1. 鎖釋放
- 必須手動釋放:lock.unlock() 需放在 finally 塊中確保執(zhí)行。
- 重入次數(shù)匹配:加鎖和解鎖次數(shù)必須一致,否則導致鎖無法釋放。
2. 中斷處理
- 響應中斷:lockInterruptibly() 和 await() 需捕獲 InterruptedException。
- 恢復中斷狀態(tài):調(diào)用 Thread.currentThread().interrupt() 保留中斷標志。
到此這篇關于Java并發(fā)編程之ReentrantLock的實現(xiàn)示例的文章就介紹到這了,更多相關Java ReentrantLock內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
SpringBoot集成MiniMax和CosyVoice實現(xiàn)文本轉語音功能
在一些需要高質(zhì)量文本轉語音(TTS)的場景中(比如:有聲書配音、播客等),比較推薦使用MiniMax、CosyVoice這些提供的音色,這些音色的效果會更加擬人、逼真,接近真人發(fā)音,本文將引導讀者從零到一把MiniMax、CosyVoice的語音合成能力整合到你的SpringBoot應用中2025-10-10
Java基于命令行調(diào)用Python腳本的方法詳解
這篇文章主要為大家詳細介紹了Java如何基于命令行實現(xiàn)調(diào)用Python腳本的方法,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學習一下2025-06-06
SpringAOP切點函數(shù)實現(xiàn)原理詳解
這篇文章主要介紹了SpringAOP切點函數(shù)實現(xiàn)原理詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2020-05-05
解決MyEclipse出現(xiàn)the user operation is waiting的問題
今天做項目的時候每次修改代碼保存后都會跳出一個框框,然后就有兩個進度條,上面寫the user operation is wating...小編去網(wǎng)上查了查解決了這個問題,下面跟大家分享一下。2018-04-04

