AQS源碼解析(7)release

釋放鎖的核心函數(shù)release:

public final boolean release(int arg) {
        if (tryRelease(arg)) {//同tryAcquire具體實(shí)現(xiàn)類有自己實(shí)現(xiàn),后面看reentrantlock的實(shí)現(xiàn)
            Node h = head;
            if (h != null && h.waitStatus != 0)//head=null的情況只有一個(gè)線程進(jìn)入,沒有初始化隊(duì)列,!=null至少說明隊(duì)列被初始化過,但是是否有后續(xù)節(jié)點(diǎn)未知,waitStatus!=0說明下個(gè)節(jié)點(diǎn)是等待的
                unparkSuccessor(h);//喚醒下個(gè)節(jié)點(diǎn)
            return true;
        }
        return false;
}

tryRelease比較簡(jiǎn)單,比較state的值是否減到0

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;
}
private void unparkSuccessor(Node node) {
        int ws = node.waitStatus;
        //ws小于0表示正常排隊(duì)線程,先設(shè)置為0
        if (ws < 0)
            compareAndSetWaitStatus(node, ws, 0);

        Node s = node.next;
       //這里著實(shí)沒想出什么時(shí)候s會(huì)null,除了手動(dòng)去修改隊(duì)列,我理解只是作者的保護(hù)
       //waitStatus>0表示下個(gè)線程是被cancel狀態(tài)
       //進(jìn)這個(gè)是從隊(duì)尾開始找,找最近的正常排隊(duì)的線程
        if (s == null || s.waitStatus > 0) {
            s = null;
            for (Node t = tail; t != null && t != node; t = t.prev)
                if (t.waitStatus <= 0)
                    s = t;
        }
        if (s != null)
            LockSupport.unpark(s.thread);//喚醒下一個(gè)等待隊(duì)列中的線程
 }
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

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