java鎖機(jī)制分類以及實(shí)現(xiàn)原理剖析(1)--公平鎖與非公平鎖

我們最早接觸java線程鎖,其實(shí)也就是syncronized和ReentrantLock,ReentrantLock作為L(zhǎng)ock的一個(gè)實(shí)現(xiàn),其實(shí)構(gòu)造時(shí),也分為公平鎖與非公平鎖之分。
先看源碼:

 /**
     * Creates an instance of {@code ReentrantLock} with the
     * given fairness policy.
     *
     * @param fair {@code true} if this lock should use a fair ordering policy
     */
    public ReentrantLock(boolean fair) {
        sync = fair ? new FairSync() : new NonfairSync();
    }

這一部分就是ReentrantLock的構(gòu)造方法,傳入的參數(shù)不同構(gòu)造的鎖類型就將不同。
下面先看看一下公平鎖的實(shí)現(xiàn),源碼如下:

/**
     * Sync object for fair locks
     */
    static final class FairSync extends Sync {
        private static final long serialVersionUID = -3000897897090466540L;

        final void lock() {
            acquire(1);
        }

        /**
         * Fair version of tryAcquire.  Don't grant access unless
         * recursive call or no waiters or is first.
         */
        protected final boolean tryAcquire(int acquires) {
            final Thread current = Thread.currentThread();
            int c = getState();
            if (c == 0) {
                if (!hasQueuedPredecessors() &&
                    compareAndSetState(0, acquires)) {
                    setExclusiveOwnerThread(current);
                    return true;
                }
            }
            else if (current == getExclusiveOwnerThread()) {
                int nextc = c + acquires;
                if (nextc < 0)
                    throw new Error("Maximum lock count exceeded");
                setState(nextc);
                return true;
            }
            return false;
        }
    }

然后再貼出非公平鎖的實(shí)現(xiàn)源碼:

 /**
     * Sync object for non-fair locks
     */
    static final class NonfairSync extends Sync {
        private static final long serialVersionUID = 7316153563782823691L;

        /**
         * Performs lock.  Try immediate barge, backing up to normal
         * acquire on failure.
         */
        final void lock() {
            if (compareAndSetState(0, 1))
                setExclusiveOwnerThread(Thread.currentThread());
            else
                acquire(1);
        }

        protected final boolean tryAcquire(int acquires) {
            return nonfairTryAcquire(acquires);
        }
    }

先從概念上,我的理解是:
公平鎖: 每個(gè)等待的線程首先他們獲取鎖的機(jī)會(huì)是公平的,那么怎么保證他們是公平的呢?只能是根據(jù)申請(qǐng)鎖的順序來保證,那順序又如何保證呢,必然是有一個(gè)類似隊(duì)列的數(shù)據(jù)結(jié)構(gòu)來序列化等待的線程。
非公平鎖:從字面意思上理解,每個(gè)等待的線程獲取鎖的機(jī)會(huì)是不公平的,那他們?nèi)绾潍@取鎖呢?顯然獲取鎖的時(shí)候就該八仙過海,各顯神通了,必然會(huì)導(dǎo)致有些能力差的線程搶不到鎖。
帶著這些概念上的理解與思路我們開始重讀源碼。先從non-fair locks 開始。

非公平鎖

我們來逐行分析:
1.首先是對(duì)象序列化時(shí)候的UID。
2.lock()是一個(gè)構(gòu)建鎖的方法,tryAcquire()是一個(gè)獲取鎖的方法。
3.先看lock()方法,會(huì)先去執(zhí)行本地CAS算法,看看當(dāng)前鎖的狀態(tài)是不是0,是0的話就改為1,那么就給當(dāng)前線程排它的權(quán)限,也就是對(duì)當(dāng)前線程操作的資源加上了鎖。如果CAS算法結(jié)果不成立,然后會(huì)去獲取鎖。

  1. tryAcquire()嘗試獲取鎖方法。
/**
         * Performs non-fair tryLock.  tryAcquire is implemented in
         * subclasses, but both need nonfair try for trylock method.
         */
        final boolean nonfairTryAcquire(int acquires) {
            final Thread current = Thread.currentThread();
            int c = getState();
            if (c == 0) {
                if (compareAndSetState(0, acquires)) {
                    setExclusiveOwnerThread(current);
                    return true;
                }
            }
            else if (current == getExclusiveOwnerThread()) {
                int nextc = c + acquires;
                if (nextc < 0) // overflow
                    throw new Error("Maximum lock count exceeded");
                setState(nextc);
                return true;
            }
            return false;
        }

如果當(dāng)前資源不在同步狀態(tài),compareAndSetState(0, acquires) CAS算法看狀態(tài), setExclusiveOwnerThread(current);設(shè)置當(dāng)前線程加鎖。如果當(dāng)前線程有鎖就更新鎖狀態(tài)。

公平鎖

與非公平鎖一樣,提供lock()與tryAcquire()方法,不一樣的是fair lock多了一個(gè)對(duì)等待線程隊(duì)列的判斷,當(dāng)前線程是否處在最前。

最后編輯于
?著作權(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ù)。

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