AQS專題

1.背景

2.預備知識

2.1.park、unpark、interrupt、isInterrupted、interrupted方法的理解

一:park、unpark

1.park、unpark它不是Thread中的方法,而是LockSupport.park(),LockSupport是JUC中的對象;
2.park可以讓線程暫停 (只有在isInterrupted狀態爲false的情況下才有效),unpark可以讓暫停的線程繼續執行;

二:interrupt、isInterrupted、interrupted
1.interrupt、isInterrupted、interrupted 它是Thread中的方法;
2.interrupt 設置一箇中斷標記,interrupt()方法可以讓暫停的方法繼續執行,通俗直觀的理解是,設置打斷標記後,處於暫停狀態的線程就會被喚醒,如果是睡眠的就拋出中斷異常;
3.isInterrupted 這個好理解就是查看當前線程的中斷標記;
4.interrupted 這是一個靜態方法,只能這樣調用Thread.interrupted(),這個方法會返回當前interrupt狀態,如果interrupt=true會將其改變爲 false,反之則不成立;

系統化學習見:https://www.cnblogs.com/newAndHui/p/15939255.html

 2.2.CAS無鎖的理解

通俗的實現原理就是:在修改一個值時,先比較原來的值,在修改現在的值

compareAndSet(期望值,修改值);

compareAndSet(0,1);期望把1修改爲0;

實現代碼邏輯:

 /**
     * compareAndSet 做這個檢查,在 set 前,先比較 prev 與當前值不一致了,next 作廢,返回 false 表示失敗
     * <p>
     * 其實 CAS 的底層是 lock cmpxchg 指令(X86 架構),在單核 CPU 和多核 CPU 下都能夠保證【比較-交換】的原子性。
     * 在多核狀態下,某個核執行到帶 lock 的指令時,CPU 會讓總線鎖住,當這個核把此指令執行完畢,再
     * 開啓總線。這個過程中不會被線程的調度機制所打斷,保證了多個線程對內存操作的準確性,是原子的。
     * <p>
     * CAS 的特點
     * 結合 CAS 和 volatile 可以實現無鎖併發,適用於線程數少、多核 CPU 的場景下。
     * 1.CAS 是基於樂觀鎖的思想:最樂觀的估計,不怕別的線程來修改共享變量,就算改了也沒關係,重試在執行【修改】。
     * 2.synchronized 是基於悲觀鎖的思想:最悲觀的估計,防着其它線程來修改共享變量,當前線程上鎖後,其他線程阻塞等待。
     * 3.CAS 體現的是【無鎖併發、無阻塞併發】。
     * 因爲沒有使用 synchronized,所以線程【不會陷入阻塞】,這是效率提升的因素之一,
     * 但如果競爭激烈,可以想到重試必然頻繁發生,反而頻繁切換上下文,效率會受影響。
     * 4.特別注意:
     * 無鎖情況下,但如果競爭激烈,因爲線程要保持運行,需要CPU 的支持,雖然不會進入阻塞,但由於沒有分到時間片,仍然會進入可運行狀態,還是會導致上下文切換。
     *
     * @param amount
     */
     private AtomicInteger balance;
    @Override
    public void reduce(Integer amount) {
        // 不斷嘗試直到成功爲止
        while (true) {
            // 修改前的值
            int prev = balance.get();
            // 修改後的值
            int next = prev - amount;
            // 執行修改 compareAndSet  使用CAS樂觀鎖實現
            if (balance.compareAndSet(prev, next)) {
                break;
            }
        }
        // 簡要寫法
        // balance.addAndGet(-1 * amount);
    }
View Code

系統化學習見:https://www.cnblogs.com/newAndHui/p/15939255.html

3.AQS原理

1.AQS簡介
AQS全稱爲AbstractQueuedSynchronizer(抽象隊列同步器)。AQS是一個用來構建鎖和其他同步組件的基礎框架,
使用AQS可以簡單且高效地構造出應用廣泛的同步器,例如ReentrantLock、Semaphore、ReentrantReadWriteLock和FutureTask等等。

2.原理
AQS核心思想是,如果被請求的共享資源空閒,則將當前請求資源的線程設置爲有效的工作線程,並且將共享資源設置爲鎖定狀態。
如果被請求的共享資源被佔用,那麼就需要一套線程阻塞等待以及被喚醒時鎖分配的機制,這個機制AQS是用CLH隊列鎖實現的,
即將暫時獲取不到鎖的線程加入到隊列中。

3.CLH隊列
CLH(Craig,Landin,and Hagersten)隊列是一個虛擬的雙向隊列(虛擬的雙向隊列即不存在隊列實例,僅存在結點之間的關聯關係)。
AQS是將每條請求共享資源的線程封裝成一個CLH鎖隊列的一個結點(Node)來實現鎖的分配。

4.自己寫一個AQS

 見博客:https://www.cnblogs.com/newAndHui/p/16686194.html

5.AQS源碼解讀

完美!

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章