天天看點

源碼解讀 可重入鎖ReentrantLock 的内部類 公平鎖FairSync 和 非公平鎖NonfairSync 實作原理

變量解釋:

public abstract class AbstractOwnableSynchronizer
    implements java.io.Serializable {
    ...
    /** * The current owner of exclusive mode synchronization. * 持有該鎖的目前線程 */
    private transient Thread exclusiveOwnerThread;
    ...
}      
public abstract class AbstractQueuedSynchronizer
    extends AbstractOwnableSynchronizer
    implements java.io.Serializable {
    ...
    /**
     * The synchronization state.
     * 0: 初始狀态-無任何線程得到了鎖
     * > 0: 被線程持有, 具體值表示被目前線程持有的執行次數
     * 
     * 這個字段在解鎖的時候也需要用到。
     * 注意這個字段的修飾詞: volatile
     */
    private volatile int state;
    ...
}      

公平鎖FairSync:

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

        final void lock() {
            // AQS的acquire方法。獨占方式。嘗試擷取資源,成功則傳回true,失敗則傳回false。
            acquire(1);
        }

        /**
         * Fair version of tryAcquire.  Don't grant access unless
         * recursive call or no waiters or is first.
         * (翻譯:tryAcquiere的公平鎖實作版本,除非有遞歸、沒有等待者、或者有優先,否則不要授予鎖權限)
         */
        protected final boolean tryAcquire(int acquires) {
            final Thread current = Thread.currentThread();
            // AQS使用一個int類型的成員變量state來表示同步狀态,當state = 1時表示已經擷取了鎖,當state = 0時表示釋放了鎖。
            // getState():傳回同步狀态的目前值;
            int c = getState();
            if (c == 0) { // 如果目前線程沒有擷取過鎖,則嘗試加鎖
                //與非公平鎖不同的是,此處多了hasQueuedPredecessors()判斷,該方法是實作公平鎖的關鍵。
                //如果hasQueuedPredecessors傳回true,表示有其他線程先于目前線程等待擷取鎖,此時為了實作公平,保證等待時間最長的線程先擷取到鎖,不能執行CAS。

                //protected final boolean compareandsetstate(int expect, int update) 
                //如果目前狀态值等于預期值,則以原子方式将同步狀态設定為給定的更新值。此操作具有 volatile 讀和寫的記憶體語義。
                //參數:expect - 預期值 update - 新值
                //傳回:如果成功,則傳回 true。傳回 false 訓示實際值與預期值不相等。
                if (!hasQueuedPredecessors() &&
                    compareAndSetState(0, acquires)) {

                    // 設定占用排它鎖的線程是目前線程
                    setExclusiveOwnerThread(current);
                    return true;
                }
            }
            // getExclusiveOwnerThread(): 傳回由 setexclusiveownerthread 最後設定的線程;如果從未設定,則傳回 null。此方法不另外施加任何同步或 volatile 字段通路。
            else if (current == getExclusiveOwnerThread()) { //目前線程已經擷取到鎖,重入
                int nextc = c + acquires; // 鎖狀态計數器累加
                if (nextc < 0)
                    throw new Error("Maximum lock count exceeded");
                setState(nextc);
                return true;
            }
            return false;
        }
    }      

非公平鎖NonfairSync:

/**
     * 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);
        }
    }      

FairSync:

繼續閱讀