抽象隊列同步器AQS

    AQS全名爲AbstractQueuedSynchronizer,爲java併發包中提供的類。提供了對資源佔用,釋放,線程的等待、喚醒等接口和具體實現,java

能夠用在各類須要控制資源爭用的場景中。(ReentrantLock/CountDownLatch/Semphore)併發

   

    AQS中定義了八個比較重要的方法:ui

      acquire、acruireShared:定義了資源爭用的邏輯,若是沒拿到,則等待spa

      tryAcquire、tryAcquireShared:實際執行佔用資源的邏輯,如何斷定由使用者具體去實現線程

      release、releaseShared:定義資源釋放的邏輯,釋放以後,通知後續節點進行爭搶code

      tryRelease、tryReleaseShared:定義執行資源釋放的操做,具體的AQS使用者去實現orm

 

    資源佔用流程blog

   

 

     以ReentrantLock爲例,分析AQS的使用。因爲ReentrantLock是獨佔鎖,因此會涉及到 acquire、tryAcquire、release、tryRelease四個方法。繼承

 ReentrantLock中Sync類繼承了AQS,其中關鍵代碼以下:接口

abstract static class Sync extends AbstractQueuedSynchronizer { /** * Performs {@link Lock#lock}. The main reason for subclassing * is to allow fast path for nonfair version. */
        abstract void lock(); .... /** *非公平獲取鎖,每次獲取時都嘗試獲取一次,無論前面是否有其餘 *線程也在嘗試獲取,獲取失敗則加入等待隊列 * 獲取成功則將鎖持有者設爲當前線程 */
        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; } /** *嘗試釋放鎖 *即將state變量減一,當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; } ... }

     ReentrantLock中有公平鎖和非公平鎖兩種實現。在ReentrantLock中對應了兩個類,NonfairSync和FairSync,它們都繼承了Sync。

     FairSync關鍵代碼以下:

static final class FairSync extends Sync { ··· /** *加鎖方法,首先調用tryAcquire方法,成功則獲取鎖 *不然經過aqs提供的方法將當前線程加入等待隊列 */
        final void lock() { acquire(1); } /** *若是state爲0則嘗試獲取鎖,若是前面有線程也嘗試獲取鎖則把當前線程加入等待隊列 *state不爲0則則判斷持有鎖的線程是否時當前線程,是則state加一(鎖的可重入機制) */
        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; } }

 

      NonfairSync關鍵代碼以下:

static final class NonfairSync extends Sync { ··· /** *非公平鎖加鎖時老是先嚐試獲取鎖 *即嘗試經過CAS將state由0設爲1 * 設置失敗則調用acquire方法 */
        final void lock() { if (compareAndSetState(0, 1)) setExclusiveOwnerThread(Thread.currentThread()); else acquire(1); } /** * tryAcquire方法調用父類Sync的nonfairTryAcquire方法 */
        protected final boolean tryAcquire(int acquires) { return nonfairTryAcquire(acquires); } }

 

  接下來再查看ReentrantLock的加鎖與解鎖方法,即在調用Sync的acruire和release方法:

... public void lock() { sync.lock(); } ... public void unlock() { sync.release(1); } ...
相關文章
相關標籤/搜索