前言

隊(duì)列同步器 AbstractQueuedSynchronizer(以下簡(jiǎn)稱(chēng) AQS),是用來(lái)構(gòu)建鎖或者其他同步組件的基礎(chǔ)框架。它使用一個(gè) int 成員變量來(lái)表示同步狀態(tài),通過(guò) CAS 操作對(duì)同步狀態(tài)進(jìn)行修改,確保狀態(tài)的改變是安全的。通過(guò)內(nèi)置的 FIFO (First In First Out)隊(duì)列來(lái)完成資源獲取線(xiàn)程的排隊(duì)工作。更多關(guān)于 Java 多線(xiàn)程的文章可以轉(zhuǎn)到 這里

AQS 和 synchronized

在介紹 AQS 的使用之前,需要首先說(shuō)明一點(diǎn),AQS 同步和 synchronized 關(guān)鍵字同步(以下簡(jiǎn)稱(chēng) synchronized 同步)是采用的兩種不同的機(jī)制。首先看下 synchronized 同步,synchronized 關(guān)鍵字經(jīng)過(guò)編譯之后,會(huì)在同步塊的前后分別形成 monitorenter 和 monitorexit 這兩個(gè)字節(jié)碼指令,這兩個(gè)字節(jié)碼需要關(guān)聯(lián)到一個(gè)監(jiān)視對(duì)象,當(dāng)線(xiàn)程執(zhí)行 monitorenter 指令時(shí),需要首先獲得獲得監(jiān)視對(duì)象的鎖,這里監(jiān)視對(duì)象鎖就是進(jìn)入同步塊的憑證,只有獲得了憑證才可以進(jìn)入同步塊,當(dāng)線(xiàn)程離開(kāi)同步塊時(shí),會(huì)執(zhí)行 monitorexit 指令,釋放對(duì)象鎖。

在 AQS 同步中,使用一個(gè) int 類(lèi)型的變量 state 來(lái)表示當(dāng)前同步塊的狀態(tài)。以獨(dú)占式同步(一次只能有一個(gè)線(xiàn)程進(jìn)入同步塊)為例,state 的有效值有兩個(gè) 0 和 1,其中 0 表示當(dāng)前同步塊中沒(méi)有線(xiàn)程,1 表示同步塊中已經(jīng)有線(xiàn)程在執(zhí)行。當(dāng)線(xiàn)程要進(jìn)入同步塊時(shí),需要首先判斷 state 的值是否為 0,假設(shè)為 0,會(huì)嘗試將 state 修改為 1,只有修改成功了之后,線(xiàn)程才可以進(jìn)入同步塊。注意上面提到的兩個(gè)條件: