Lock底層原理解析-AQS-lock方法-03

前面我們做了一些預(yù)備知識(shí),現(xiàn)在我們就開始來分析lock 接口。

  • Lock 接口定義


    image.png
  • demo

// 重入鎖
private Lock lock = new ReentrantLock();
public void add () {
        try {
            lock.lock();
            System.out.println(".......");
        }finally {
            lock.unlock();
        }
    }

我們就從ReentrantLock 開始。

  • ReentrantLock
/**
     * Creates an instance of {@code ReentrantLock}.
     * This is equivalent to using {@code ReentrantLock(false)}.
     */
    private final Sync sync;
    public ReentrantLock() {// 默認(rèn)構(gòu)造器
        sync = new NonfairSync();
    }

這里呢,看不出啥東西,只知道 有個(gè) 對(duì)象叫 Sync 然后 被實(shí)例化 。sync = new NonfairSync();

-內(nèi)部類 Sync

abstract static class Sync extends AbstractQueuedSynchronizer {
    abstract void lock();
    ....................
}

在 ReentrantLock 內(nèi)部定義了一個(gè) 抽象的 內(nèi)部類 Sync。繼承 AbstractQueuedSynchronizer ,這個(gè)東西我們就叫他AQS了。

  • lock.lock(); // demo 代碼點(diǎn)進(jìn)去,我們就看到下面這段代碼。
 public void lock() {
        sync.lock(); // NonfairSync 中的 lock
    }

通過上面的分析我們知道 這里的 sync = new NonfairSync();

  • NonfairSync
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)) // CAS 設(shè)置 state 的值,state = 1 表示 獲取鎖成功。
                setExclusiveOwnerThread(Thread.currentThread()); // 記錄下獲取鎖的線程
            else // 沒有獲取鎖成功的線程就 執(zhí)行  acquire(1); 
                acquire(1); 
        }

        protected final boolean tryAcquire(int acquires) {
            return nonfairTryAcquire(acquires);
        }
    }
  • compareAndSetState(0, 1)
// AbstractQueuedSynchronizer

/**
     * The synchronization state.
     */
private volatile int state; // 默認(rèn)是 0
// expect = 0, update = 1
protected final boolean compareAndSetState(int expect, int update) { 
        // See below for intrinsics setup to support this
        // stateOffset ,state 字段的內(nèi)存地址值
        return unsafe.compareAndSwapInt(this, stateOffset, expect, update);
    }

通過 CAS 對(duì) AbstractQueuedSynchronizer 中的 state 的值 更新,如果 更新成功,表示 當(dāng)前線程獲取鎖成功,否則 阻塞,繼續(xù)等待。這里就看出來 AQS 其實(shí) 是采用樂觀鎖的方式來 實(shí)現(xiàn)線程 的鎖控制。

我們大致來整理一下 我們?cè)谑褂?Lock 接口來控制多線程的時(shí)候的 調(diào)用鏈:

  1. private Lock lock = new ReentrantLock();
  2. lock.lock();
  3. NonfairSync.lock();
    4.AbstractQueuedSynchronizer.compareAndSetState(0, 1)
  1. 創(chuàng)建 重入鎖對(duì)象 Lock lock = new ReentrantLock();
  2. 調(diào)用 lock() 方法 ,lock.lock();
  3. ReentrantLock 中的lock 方法,調(diào)用的是 NonfairSync 對(duì)象的 lock() 方法。
  4. NonfairSync#lock() 使用 AQS 中的 compareAndSetState(0, 1) 方法 來更新 AQS 中 state 屬性的值,更新為1 表示當(dāng)前線程獲取鎖成功。

上面我們分析了 lock 對(duì)象 中 lock 方法是如何 控制線程獲取鎖的,后面我們就接著分析,沒有獲取到鎖的對(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ù)。

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