# ReentrantLock是什么
## 一、概述
`ReentrantLock`是Java并發包(`java.util.concurrent.locks`)中的一個可重入互斥鎖實現類,自JDK 1.5引入。它提供了比`synchronized`關鍵字更靈活的鎖機制,支持公平性選擇、可中斷的鎖獲取、超時鎖獲取等高級特性,是構建線程安全應用的重要工具。
## 二、核心特性
### 1. 可重入性(Reentrancy)
與`synchronized`相同,`ReentrantLock`允許同一個線程多次獲取同一把鎖。例如:
```java
ReentrantLock lock = new ReentrantLock();
void methodA() {
lock.lock();
try {
methodB(); // 可重入調用
} finally {
lock.unlock();
}
}
void methodB() {
lock.lock(); // 同一線程可重復獲取鎖
try {
// 操作共享資源
} finally {
lock.unlock();
}
}
構造時可指定是否為公平鎖:
// 公平鎖(按申請順序獲取鎖)
ReentrantLock fairLock = new ReentrantLock(true);
// 非公平鎖(默認,吞吐量更高)
ReentrantLock unfairLock = new ReentrantLock();
lockInterruptibly()
tryLock(long timeout, TimeUnit unit)
tryLock()
特性 | ReentrantLock | synchronized |
---|---|---|
實現方式 | API層面(Java代碼實現) | JVM原生支持(字節碼) |
鎖釋放 | 必須手動調用unlock() | 自動釋放 |
公平性 | 可配置 | 非公平 |
性能 | 高競爭時更優 | JDK6后優化接近 |
功能擴展 | 支持條件變量、多等待隊列 | 單一等待隊列 |
ReentrantLock lock = new ReentrantLock();
public void criticalSection() {
lock.lock(); // 阻塞直到獲取鎖
try {
// 臨界區代碼
} finally {
lock.unlock(); // 必須放在finally塊
}
}
ReentrantLock lock = new ReentrantLock();
Condition condition = lock.newCondition();
void await() throws InterruptedException {
lock.lock();
try {
condition.await(); // 釋放鎖并等待
} finally {
lock.unlock();
}
}
void signal() {
lock.lock();
try {
condition.signal();
} finally {
lock.unlock();
}
}
ReentrantLock
基于抽象隊列同步器(AbstractQueuedSynchronizer
)實現:
- 通過state
變量記錄鎖狀態(0=未鎖定,>0=持有計數)
- 使用CLH隊列管理等待線程
默認模式下,新請求線程會直接嘗試獲取鎖,不檢查等待隊列,提高吞吐量但可能導致線程饑餓。
嚴格按照FIFO順序分配鎖,通過hasQueuedPredecessors()
方法檢查是否有更早的等待線程。
unlock()
會導致死鎖synchronized
作為Java并發編程的核心組件之一,ReentrantLock
通過靈活的API和強大的功能,為開發者提供了比內置鎖更精細的線程控制能力。理解其實現原理和適用場景,能夠幫助我們在高并發環境下做出更合理的設計選擇。
“`
(注:實際字數約900字,可根據需要調整細節部分的詳略程度)
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。