ReentantLock核心代碼

Lock接口

Reentrant實現(xiàn)了Lock接口,Lock接口主要定義了如下幾個方法:

//加鎖
void lock();
//獲取鎖
boolearn tryLock();
//獲取鎖(設(shè)置超時等待時間)
boolearn tryLock(long time, TimeUnit unit) throw InterruptedException;
//釋放鎖
void unlock();

ReentrantLock結(jié)構(gòu)

ReentrantLock結(jié)構(gòu)

默認(rèn)構(gòu)造創(chuàng)建的是一個非公平鎖,可以通過參數(shù)控制創(chuàng)建的是公平的還是非公平的;

    //默認(rèn)的構(gòu)造為非公平重入鎖
    public ReentrantLock() {
        sync = new NonfairSync();
    }
    
    //根據(jù)fair參數(shù)判斷創(chuàng)建的是公平鎖還是非公平
    public ReentrantLock(boolean fair) {
        sync = fair ? new FairSync() : new NonfairSync();
    }

公平鎖:按照線程先來后到順序獲取鎖,后到的線程只能等前面的線程都獲取鎖完畢才執(zhí)行獲取鎖的操作,執(zhí)行有序
非公平鎖:不按照線程先來后到的時間順序進行競爭鎖,后到的線程也能夠獲取到鎖

ReentrantLock內(nèi)部類:NonfairSync,F(xiàn)airSync

Reentrant都是通過NonfairSync和FairSync來實現(xiàn)鎖的功能,它倆的父類Sync則繼承了AbstractQueuedSynchronizer,AQS是JUC框架核心。

加鎖lock()

//公平鎖
//static final class FairSync extends Sync
final void lock() {
  acquire(1);
}

//非公平鎖
// static final class NonfairSync extends Sync {
final void lock() {
  //CAS更新同步狀態(tài)值state,鎖占有線程設(shè)置為當(dāng)前線程
  if (compareAndSetState(0, 1))
    setExclusiveOwnerThread(Thread.currentThread());
  else
    acquire(1);
}

先看一下acquire(1)方法,此方法定義在Sync的父類AbstractQueuedSynchronizer中

//AbstractQueuedSynchronizer.java
//獲取鎖,此部分邏輯定義在父類中,NonfairSync和FairSync通用,只是tryAcquire(arg) 有不同的實現(xiàn)
public final void acquire(int arg) {
        //獲取鎖失敗  &&  acquireQueued方法會將線程排隊到隊列并且返回線程是否需要中斷
        if (!tryAcquire(arg) && acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
            selfInterrupt();
}

/**
* 中斷當(dāng)前線程
**/
static void selfInterrupt() {
        Thread.currentThread().interrupt();
}

公平鎖的tryAcquire實現(xiàn)

//static final class FairSync extends Sync
//嘗試獲取鎖的邏輯(公平鎖),獲取成功返回true,失敗返回false
protected final boolean tryAcquire(int acquires) {
    //獲取當(dāng)前線程
    final Thread current = Thread.currentThread();
    //獲取同步狀態(tài)的當(dāng)前值
    int c = getState();
    if (c == 0) {
        //判斷前面是否有排隊的線程,沒有的話CAS設(shè)置線程的state值為1
        //與非公平鎖的獲取鎖實現(xiàn)唯一區(qū)別的地方
        //非公平鎖不需要hasQueuedPredecessors() 判斷前面是否有排隊的線程
        if (!hasQueuedPredecessors() && compareAndSetState(0, acquires)) {
            //設(shè)置占用線程為當(dāng)前線程
            setExclusiveOwnerThread(current);
            return true;
        }
    } else if (current == getExclusiveOwnerThread()) {//重入,當(dāng)前線程就是獨占線程
        int nextc = c + acquires;
        if (nextc < 0) 
            throw new Error("Maximum lock count exceeded");
        setState(nextc);
        return true;
    }
    return false;
}

非公平鎖的tryAcquire實現(xiàn)

//Sync object for non-fair locks
 protected final boolean tryAcquire(int acquires) {
    return nonfairTryAcquire(acquires);
 }

//nonfairTryAcquire實現(xiàn)在父類Sync中
final boolean nonfairTryAcquire(int acquires) {
    //獲取當(dāng)前線程
    final Thread current = Thread.currentThread();
    //獲取同步狀態(tài)值
    int c = getState();
    if (c == 0) {
        //與公平鎖的獲取鎖實現(xiàn)唯一區(qū)別的地方
        //公平鎖要hasQueuedPredecessors() 判斷前面是否有排隊的線程
        if (compareAndSetState(0, acquires)) {
            setExclusiveOwnerThread(current);
            return true;
        }
    } else if (current == getExclusiveOwnerThread()) {//鎖占有線程就是當(dāng)前線程,重入
        int nextc = c + acquires;
        if (nextc < 0) // overflow
          throw new Error("Maximum lock count exceeded");
        //更新同步狀態(tài)值
        setState(nextc);
        return true;
    }
    return false;
}

tryAcquire(arg)返回false的話,執(zhí)行acquireQueued進行添加到隊列,此方法定義在AbstractQueuedSynchronizer中,參數(shù)需要addWaiter(Node.EXCLUSIVE)返回的Node。

//AbstractQueuedSynchronizer.java
/**
* 為當(dāng)前線程和給定模式創(chuàng)建和排隊節(jié)點
**/
private Node addWaiter(Node mode) {
    //創(chuàng)建當(dāng)前線程節(jié)點
    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);
    return node;
}

/**
* 嘗試排隊
**/
final boolean acquireQueued(final Node node, int arg) {
    boolean failed = true;
    try {
        boolean interrupted = false;
        for (;;) {
            final Node p = node.predecessor();
            //前面無排隊線程 && 獲取鎖成功
            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);
    }
}

解鎖lock()

解鎖方法定義在AbstractQueuedSynchronizer中,實現(xiàn)在ReentrantLock的內(nèi)部類Sync中

//ReentrantLock.java
public void unlock() {
    sync.release(1);
}

//AbstractQueuedSynchronizer.java
public final boolean release(int arg) {
    //嘗試獲取鎖
    if (tryRelease(arg)) {
        Node h = head;
        if (h != null && h.waitStatus != 0) 
            //喚醒等待的線程獲取鎖
            unparkSuccessor(h);
        return true;
    }
    return false;
}

//ReentrantLock.Sync
protected final boolean tryRelease(int releases) {
    //計算狀態(tài)值
    int c = getState() - releases;
    //當(dāng)前線程沒有占有鎖
    if (Thread.currentThread() != getExclusiveOwnerThread()) 
        throw new IllegalMonitorStateException();
    boolean free = false;
    if (c == 0) {
        //釋放鎖成功
        free = true;
        setExclusiveOwnerThread(null);
    }
    //更新狀態(tài)值
    setState(c);
    return free;
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容