一、J.U.C之AQS介紹:
1、概述:J.U.C表示jdk中java.util.concurrente 包裏的內容,是從jdk6中引入的java併發包。J.U.C大大提高了java程序的併發性能。
而AQS被認爲是J.U.C的核心,指AbstractQueuedSynchronizer 的縮寫。AbstractQueuedSynchronizer這個類提供了基於firstIn firstOut隊列。這個隊列可以構建鎖或者其他相關的同步裝置的基礎框架。
作爲一個雙向列表,結構大致如下:
注:上方的sync queue 是所說的雙向隊列,有頭結點和尾結點。
而下方的condition queue 不是必須有的,而且在有condition時纔會出現,並且condition的數量可以不確定。
2、AQS設計特點:
》使用Node實現FIFO隊列,可以用於構建鎖或者其他同步裝置的基礎框架。
》利用了一個int類型表示狀態;在AQS類中,有一個成員變量state,而基於AQS有一個同步 組件 RetreenLock 鎖,在這個鎖中,state表示獲取到線程的數量。如果爲0,表示還沒有線程獲取鎖,如果是1,表示有一個線程獲取到鎖,如果是兩個及以上,表示重複鎖的數量。
》使用方法是繼承。AQS基於模板方法進行設計,使用者需要繼承於AQS,子類需要重寫其中的方法。
》子類通過繼承並通過實現它的方法管理其狀態{acquire 和 release }的方法操縱狀態;
》可以同時實現排它鎖和共享鎖模式(獨佔、共享)。注:使用者只會使用獨佔或者共享其中一套API來實現,而不是兩個同時使用。
3、AQS使用時的設計思路:
AQS內部維護了一個cl 隊列來管理鎖,線程會首先獲取鎖,如果獲取鎖失敗,就將當前線程以及等待狀態等信息包成一個Node結點加入到之前所說的隊列sync中,之後會不斷地循環嘗試獲取鎖。它的條件是當前結點爲head直接的後繼纔會去嘗試,如果失敗就會阻塞自己,直到自己被喚醒。而當持有鎖的線程釋放鎖時會喚醒隊列中的後繼線程。
基於這樣基礎的設計思路,jdk中提供了很多基於AQS的子類,即AQS同步組件。
4、AQS同步組件有哪些呢?
》CountDownLatch : 閉鎖,通過計數來保證線程是否需要一直被阻塞。
》Semaphore :能夠控制同一時刻的併發數目
》CyclicBarrier : 它和CountDownLatch很像,都能阻塞進程。
》ReentranLock :很重要,之後會有詳細介紹。
》FutureTask :之後詳細介紹。
其他的還有很多,但如上更常用。