導航:首頁 > 源碼編譯 > 同步器aqs框架源碼

同步器aqs框架源碼

發布時間:2023-01-01 09:27:06

㈠ AQS源碼解析(6)acquireInterruptibly

reentrantlock中有lockInterruptibly函數,表示可響應中斷,之前講的lock是不會響應中斷的:

lockInterruptibly核心函數:

doAcquireInterruptibly:

㈡ 多線程-AQS總結

一個排他鎖ReentrantLock,一個ReenTrantReadWriteLock,3個同步器分別是CountDownLatch、Semaphore、CyclicBarrier(內部直接使用ReentrantLock,其他都有一個內部類Sync extends AQS)

如上圖Node節點,下面解析一下屬性

其中waitStatus是個枚舉

源碼閱讀見另外一篇博客

例如現在有3個線程A、B、C按順序獲取鎖,並且A線程一直佔用鎖

源碼閱讀見另外一篇博客

例如現在有6個線程A(讀)、B(讀)、C(寫)、D(讀)、E(讀)、F(寫)按順序獲取鎖

源碼閱讀見另外一篇博客

例如,主線程A創建CountDownLatch(2),創建2條線程的線程池,線程B、C

例如,主線程A創建CyclicBarrier(2,屏障點方法),創建2條線程的線程池,線程B、C

例如,線程A創建Semaphore(2),創建3條線程的線程池,線程B、C、D

參考地址: https://blog.csdn.net/wangnanwlw/article/details/109509685?utm_medium=distribute.pc_relevant.none-task-blog-OPENSEARCH-1.not_use_machine_learn_pai&depth_1-utm_source=distribute.pc_relevant.none-task-blog-OPENSEARCH-1.not_use_machine_learn_pai

㈢ AQS研究系列(一)--Unsafe使用

為了研究AQS,我們先來學習下java中cas(Compare And Swap)的基礎Unsafe類的使用

Unsafe產生於java無法向c那樣操作底層操作系統,但一些場景又需要相關操作.所以此類提供了一些java語言對於操作系統內存層面操作的API.這顯然被認為是不安全的,所以此類是不公開的,不建議被java應用直接使用.
但現實中已經有大量的java並發相關操作的框架在使用它了....據說此類在計劃廢棄中.

Unsafe能操作內存?這個是什麼概念?都有哪些操作呢?

其實最明顯的是它大量方法都是直接操作內存地址進行操作的.方法可以分為下面幾類:

我們可以使用LockSupport類進行操作

a. LockSupport.park()對應Unsafe的Unsafe.park(false, 0L)------>給當前所在線程加鎖,第一個參數表示true為精度型單位為納秒,false單位毫秒,第二次參數表示等待時間;

b. LockSupport.park.unpark --------->Thread thread對應Unsafe的UNSAFE.unpark(thread)方法(解鎖指定線程)
如果,我們直接使用Unsafe,是這樣子的:

我們還可以通過Unsafe類獲取對象的屬性值.因為Unsafe類是直接操作內存的,所以需要我們獲得對應的屬性內存地址,如下操作:

如下操作,通過unsafe類實現cas原子操作.

好了,上面就是unsafe的基本幾種使用,其也是aqs框架中cas操作的基礎.下面我們進行aqs相關學習.

AQS研究系列(二)--線程狀態和interrupt()、interrupted()、isInterrupted等方法學習
AQS研究系列(三)--AbstractQueuedSynchronizer源碼分析

㈣ aqs原理是什麼

aqs原理:

是一個用於構建鎖和同步器的框架,它能降低構建鎖和同步器的工作量,還可以避免處理多個位置上發生的競爭問題,在基於AQS構建的同步器中,只可能在一個時刻發生阻塞,從而降低上下文切換的開銷,並提高吞吐量。

相關信息:

AQS內部實現了兩個隊列,一個同步隊列,一個條件隊列。

同步隊列的作用是:當線程獲取資源失敗之後,就進入同步隊列的尾部保持自旋等待,不斷判斷自己是否是鏈表的頭節點,如果是頭節點,就不斷參試獲取資源,獲取成功後則退出同步隊列。

條件隊列是為Lock實現的一個基礎同步器,並且一個線程可能會有多個條件隊列,只有在使用了Condition才會存在條件隊列。

㈤ J.U.C|同步隊列(CLH)

在上篇我們聊到AQS的原理,具體參見 《J.U.C|帶你走進AQS的內心世界》 。

這篇我們來給大家聊聊AQS中核心同步隊列(CLH)。

同步隊列

一個FIFO雙向隊列,隊列中每個節點等待前驅節點釋放共享狀態(鎖)被喚醒就可以了。

AQS如何使用它?

AQS依賴它來完成同步狀態的管理,當前線程如果獲取同步狀態失敗時,AQS則會將當前線程已經等待狀態等信息構造成一個節點(Node)並將其加入到CLH同步隊列,同時會阻塞當前線程,當同步狀態釋放時,會把首節點喚醒(公平鎖),使其再次嘗試獲取同步狀態。

Node節點面貌?

CLH同步隊列的結構圖

這里是基於CAS(保證線程的安全)來設置尾節點的。

如上圖了解了同步隊列的結構, 我們在分析其入列操作在簡單不過。無非就是將tail(使用CAS保證原子操作)指向新節點,新節點的prev指向隊列中最後一節點(舊的tail節點),原隊列中最後一節點的next節點指向新節點以此來建立聯系,來張圖幫助大家理解。

源碼
源碼我們可以通過AQS中的以下兩個方法來了解下
addWaiter方法

先通過addWaiter(Node node)方法嘗試快速將該節點設置尾成尾節點,設置失敗走enq(final Node node)方法

enq

通過「自旋」也就是死循環的方式來保證該節點能順利的加入到隊列尾部,只有加入成功才會退出循環,否則會一直循序直到成功。

上述兩個方法都是通過compareAndSetHead(new Node())方法來設置尾節點,以保證節點的添加的原子性(保證節點的添加的線程安全。)

同步隊列(CLH)遵循FIFO,首節點是獲取同步狀態的節點,首節點的線程釋放同步狀態後,將會喚醒它的後繼節點(next),而後繼節點將會在獲取同步狀態成功時將自己設置為首節點,這個過程非常簡單。如下圖

設置首節點是通過獲取同步狀態成功的線程來完成的(獲取同步狀態是通過CAS來完成),只能有一個線程能夠獲取到同步狀態,因此設置頭節點的操作並不需要CAS來保證,只需要將首節點設置為其原首節點的後繼節點並斷開原首節點的next(等待GC回收)應用即可。

聊完後我們來總一下,同步隊列就是一個FIFO雙向對隊列,其每個節點包含獲取同步狀態失敗的線程應用、等待狀態、前驅節點、後繼節點、節點的屬性類型以及名稱描述。

其入列操作也就是利用CAS(保證線程安全)來設置尾節點,出列就很簡單了直接將head指向新頭節點並斷開老頭節點聯系就可以了。

閱讀全文

與同步器aqs框架源碼相關的資料

熱點內容
小愛同學app里怎麼設置鬧鍾 瀏覽:626
微信小程序題庫源碼 瀏覽:734
國內程序員女高管 瀏覽:881
程序員會壓抑 瀏覽:682
物探編程 瀏覽:302
vuepdf預覽 瀏覽:327
迷你世界出編程軟體了 瀏覽:673
res文件夾有哪些 瀏覽:142
交通信號燈單片機課程設計 瀏覽:826
如何測試流媒體伺服器的並發能力 瀏覽:161
溯源碼有分國家認證的嗎 瀏覽:218
如何通過app查詢產檢報告 瀏覽:944
拉結爾安卓手機怎麼用 瀏覽:695
驅動級進程代理源碼 瀏覽:782
androidshape畫線 瀏覽:511
程序員想辭職被拒絕 瀏覽:101
java面試邏輯 瀏覽:749
如何下載全英文app 瀏覽:724
js函數式編程指南 瀏覽:380
為什麼安卓手機相機啟動會卡 瀏覽:341