ReentrantLock

看了下J.U.C併發包下的ReentrantLock源碼,費了很多勁,作個小總結吧,儘可能用通俗易懂的語言描述,配上一些圖說明。java

ReentrantLock介紹編程

ReentrantLock是基於AbstractQueuedSynchronizer(AQS框架)設計的,類裏面有一個私有sync成員屬性,其類型爲AbstractQueuedSynchronizer;併發

那麼什麼是AQS框架呢?AQS是由大神Doug Lea設計的,他寫了一篇論文叫《The java.util.concurrent Synchronizer Framework 》,裏面詳細描述了AQS的設計思想,想看中文翻譯的,能夠去併發編程網裏閱讀,連接框架

我這裏簡要說明下,AQS主要是維護了一個int類型的state屬性,一個非阻塞、先進先出的線程等待隊列;其中state是用volatile修飾的,保證線程之間的可見性,隊列的入隊和出對操做都是無鎖操做,基於自旋鎖和CAS實現;另外AQS分爲兩種模式:獨佔模式和共享模式,本文討論的ReentrantLock,主要涉及AQS的獨佔模式源碼分析

回過頭來講ReentrantLock,其內部有三個內部類Sync、NonfairSync和FairSync,其中NonfairSync和FairSync繼承SyncSync繼承AbstractQueuedSynchronizer,這三個內部類主要是爲了實現父類AbstractQueuedSynchronizer中未實現的tryRelease(int)和tryAcquire(int)方法;ui

其實ReentrantLock類自己並無實現什麼新功能,仔細觀察其下面的方法,發現都是經過調用sync的方法去實現的,以下所示:spa

    //省略前面部分...
    public boolean tryLock() {
        return sync.nonfairTryAcquire(1);
    }
    public boolean tryLock(long timeout, TimeUnit unit) throws InterruptedException {
        return sync.tryAcquireNanos(1, unit.toNanos(timeout));
    }
    public void unlock() {
        sync.release(1);
    }
    public Condition newCondition() {
        return sync.newCondition();
    }
    public boolean isHeldByCurrentThread() {
        return sync.isHeldExclusively();
    }
    //省略後面部分...

源碼分析線程

先看一下咱們平時都是怎樣使用ReentrantLock的,以下代碼:翻譯

        ReentrantLock lock = new ReentrantLock();
        lock.lock();

        try {
            // do something
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }

這裏的ReentrantLock是一個非公平獨佔鎖,其保證do something在同一時刻只有一個線程能訪問,當有線程正在執行do something裏的代碼時,其它線程將會等待。設計

那麼,咱們就先從lock方法開始,分析ReentrantLock是如何實現非公平獨佔鎖的;

ReentrantLock的lock方法調用的是synclock方法,而sync是在構造方法裏初始化的,因爲咱們未傳入參數,默認爲NonfairSync類型;

lock方法,調用synclock方法:

    public void lock() {
        sync.lock();
    }

無參構造方法,默認爲非公平鎖:

    public ReentrantLock() {
        sync = new NonfairSync();
    }

按照執行步驟,轉到NonfairSync的lock方法:

 

接着調用:

相關文章
相關標籤/搜索