Java並發包源碼學習之AQS架構(一)概述

來源:互聯網
上載者:User

標籤:

AQS其實就是java.util.concurrent.locks.AbstractQueuedSynchronizer這個類。 閱讀Java的並發包源碼你會發現這個類是整個java.util.concurrent的核心之一,也可以說是閱讀整個並發包源碼的一個突破口。

比如讀ReentrantLock的源碼你會發現其核心是它的一個內部類Sync:

 

整個包中很多類的結構都是如此,比如Semaphore,CountDownLatch都有一個內部類Sync,而所有的Sync都是繼承自AbstractQueuedSynchronizer。 所以說想要讀懂Java並發包的代碼,首先得讀懂這個類。

AQS簡核心是通過一個共用變數來同步狀態,變數的狀態由子類去維護,而AQS架構做的是:

  • 線程阻塞隊列的維護
  • 線程阻塞和喚醒

共用變數的修改都是通過Unsafe類提供的CAS操作完成的。AbstractQueuedSynchronizer類的主要方法是acquirerelease,典型的模板方法, 下面這4個方法由子類去實現:

protected boolean tryAcquire(int arg)protected boolean tryRelease(int arg)protected int tryAcquireShared(int arg)protected boolean tryReleaseShared(int arg)

acquire方法用來擷取鎖,返回true說明線程擷取成功繼續執行,一旦返回false則線程加入到等待隊列中,等待被喚醒,release方法用來釋放鎖。 一般來說實現的時候這兩個方法被封裝為lockunlock方法。

下面的SimpleLock類實現了一個最簡單非重入的互斥鎖的功能,實際上它就是ThreadPoolExecutor$Worker的實現(以後的文章會提到這個類)。

class SimpleLock extends AbstractQueuedSynchronizer {    private static final long serialVersionUID = -7316320116933187634L;    public SimpleLock() {    }    protected boolean tryAcquire(int unused) {        if (compareAndSetState(0, 1)) {            setExclusiveOwnerThread(Thread.currentThread());            return true;        }        return false;    }    protected boolean tryRelease(int unused) {        setExclusiveOwnerThread(null);        setState(0);        return true;    }    public void lock() {        acquire(1);    }    public boolean tryLock() {        return tryAcquire(1);    }    public void unlock() {        release(1);    }    public boolean isLocked() {        return isHeldExclusively();    }}
public static void main(String[] args) throws InterruptedException {    final SimpleLock lock = new SimpleLock();    lock.lock();    for (int i = 0; i < 10; i++) {        new Thread(new Runnable() {            @Override            public void run() {                lock.lock();                System.out.println(Thread.currentThread().getId() + " acquired the lock!");                lock.unlock();            }        }).start();        // 簡單的讓線程按照for迴圈的順序阻塞在lock上        Thread.sleep(100);    }    System.out.println("main thread unlock!");    lock.unlock();}

運行上面的測試代碼,結果如下:

main thread unlock!9 acquired the lock!10 acquired the lock!11 acquired the lock!12 acquired the lock!13 acquired the lock!14 acquired the lock!15 acquired the lock!16 acquired the lock!17 acquired the lock!18 acquired the lock!

會發現等待的線程是按照阻塞時的順序依次擷取到鎖的。 這是因為AQS是基於一個叫CLH lock queue的一個變種來實現線程阻塞隊列的,我們下一篇文章就來簡單瞭解下CLH lock queue。

後續文章計劃如下:

  • 《Java並發包源碼學習之AQS架構(二)CLH lock queue和自旋鎖》
  • 《Java並發包源碼學習之AQS架構(三)LockSupport》
  • 《Java並發包源碼學習之AQS架構(四)AbstractQueuedSynchronizer源碼分析》
  • 《Java並發包源碼學習之AQS架構(五)ConditionObject源碼分析》

  ……

  • 《Java並發包源碼學習之鎖(一)概述》
  • 《Java並發包源碼學習之鎖(二)ReentrantLock源碼分析》

  ……

  • 《Java並發包源碼學習之線程池(一)概述》
  • 《Java並發包源碼學習之線程池(二)ThreadPoolExecutor源碼分析》

  ……

學習Java並發包源碼的初衷是為了搞清之前遇到的一個問題,其實很早之前就打算看這塊的源碼但一直沒看下去,所以說 看源碼一定要有目的不能為了看而看。

 

Java並發包源碼學習之AQS架構(一)概述

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.