Java 併發程式設計(九) -- ReentrantLock 原始碼分析

我很醜發表於2020-03-13

1. 類的定義

public class ReentrantLock implements Lock, java.io.Serializable
複製程式碼

從類的定義中可以看出

  • ReentrantLock實現了Lock介面
  • ReentrantLock實現了java.io.Serializable介面,表示支援序列化

2. 欄位屬性

//序列化版本號
private static final long serialVersionUID = 7373984872572414699L;
//同步器,實現了所有的同步機制。是AbstractQueuedSynchronizer的子類
private final Sync sync;
複製程式碼

從欄位屬性中可以看出

  • ReentranLock最核心的就是同步器Sync,所有的操作都是通過它來完成的

3. 構造方法

//空的預設構造方法
public ReentrantLock() {
    	//預設是非公平鎖
        sync = new NonfairSync();
    }

//傳入一個bool物件,指定公平鎖還是非公平鎖 true 公平鎖; false 非公平鎖
 public ReentrantLock(boolean fair) {
        sync = fair ? new FairSync() : new NonfairSync();
    }
複製程式碼

從構造方法可以看出

  • ReentrantLock的構造方法只是為了初始化Sync物件

4. 方法

lock 方法

//獲取鎖
public void lock() {
    	//呼叫sync的lock方法獲取鎖
        sync.lock();
    }
複製程式碼

lockInterruptibly 方法

//獲取鎖,如果當前執行緒已經中斷,丟擲異常
public void lockInterruptibly() throws InterruptedException {
        sync.acquireInterruptibly(1);
    }
複製程式碼

tryLock 方法

//嘗試獲取鎖
public boolean tryLock() {
        return sync.nonfairTryAcquire(1);
    }

//嘗試獲取鎖,指定超時時間
public boolean tryLock(long timeout, TimeUnit unit)
            throws InterruptedException {
        return sync.tryAcquireNanos(1, unit.toNanos(timeout));
    }
複製程式碼

unlock 方法

//釋放鎖
public void unlock() {
        sync.release(1);
    }
複製程式碼

newCondition 方法

//獲取一個Condition例項
public Condition newCondition() {
        return sync.newCondition();
    }
複製程式碼

getHoldCount 方法

//獲取當前執行緒對鎖的獲取次數,注意 ReentrantLock是重入鎖,可以多次獲取鎖
public int getHoldCount() {
        return sync.getHoldCount();
    }
複製程式碼

isHeldByCurrentThread 方法

//查詢該鎖是否被當前執行緒持有
public boolean isHeldByCurrentThread() {
        return sync.isHeldExclusively();
    }
複製程式碼

isLocked 方法

//查詢是否有執行緒持有該鎖
public boolean isLocked() {
        return sync.isLocked();
    }
複製程式碼

isFair 方法

//查詢該鎖是否為公平鎖
public final boolean isFair() {
        return sync instanceof FairSync;
    }
複製程式碼

getOwner 方法

//獲取擁有該鎖的當前執行緒
protected Thread getOwner() {
        return sync.getOwner();
    }
複製程式碼

hasQueuedThreads 方法

//查詢是否有執行緒正在等待獲取該鎖
public final boolean hasQueuedThreads() {
        return sync.hasQueuedThreads();
    }

//查詢是否給定的執行緒正在等待獲取該鎖
public final boolean hasQueuedThread(Thread thread) {
        return sync.isQueued(thread);
    }
複製程式碼

getQueueLength 方法

//獲取等待獲取該鎖執行緒的數量
public final int getQueueLength() {
        return sync.getQueueLength();
    }
//獲取等待獲取該鎖執行緒,以集合方法返回
protected Collection<Thread> getQueuedThreads() {
        return sync.getQueuedThreads();
    }
複製程式碼

hasWaiters 方法

//查詢是否有任何執行緒正在等待與此鎖關聯的給定條件
public boolean hasWaiters(Condition condition) {
        if (condition == null)
            throw new NullPointerException();
        if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
            throw new IllegalArgumentException("not owner");
        return sync.hasWaiters((AbstractQueuedSynchronizer.ConditionObject)condition);
    }
複製程式碼

getWaitQueueLength 方式

//返回等待與此鎖關聯給定條件的執行緒數
public int getWaitQueueLength(Condition condition) {
        if (condition == null)
            throw new NullPointerException();
        if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
            throw new IllegalArgumentException("not owner");
        return sync.getWaitQueueLength((AbstractQueuedSynchronizer.ConditionObject)condition);
    }
複製程式碼

getWaitingThreads 方法

//返回等待與此鎖關聯給定條件的執行緒集合
protected Collection<Thread> getWaitingThreads(Condition condition) {
        if (condition == null)
            throw new NullPointerException();
        if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
            throw new IllegalArgumentException("not owner");
        return sync.getWaitingThreads((AbstractQueuedSynchronizer.ConditionObject)condition);
    }
複製程式碼

可以看出,ReentrantLock中所有的方法都是通過Sync物件來實現的

相關文章