前言
隊列同步器 AbstractQueuedSynchronizer(以下簡稱 AQS),是用來構建鎖或者其他同步組件的基礎框架。它使用一個 int 成員變量來表示同步狀態(tài),通過 CAS 操作對同步狀態(tài)進行修改,確保狀態(tài)的改變是安全的。通過內(nèi)置的 FIFO (First In First Out)隊列來完成資源獲取線程的排隊工作。更多關于 Java 多線程的文章可以轉到 這里
AQS 和 synchronized
在介紹 AQS 的使用之前,需要首先說明一點,AQS 同步和 synchronized 關鍵字同步(以下簡稱 synchronized 同步)是采用的兩種不同的機制。首先看下 synchronized 同步,synchronized 關鍵字經(jīng)過編譯之后,會在同步塊的前后分別形成 monitorenter 和 monitorexit 這兩個字節(jié)碼指令,這兩個字節(jié)碼需要關聯(lián)到一個監(jiān)視對象,當線程執(zhí)行 monitorenter 指令時,需要首先獲得獲得監(jiān)視對象的鎖,這里監(jiān)視對象鎖就是進入同步塊的憑證,只有獲得了憑證才可以進入同步塊,當線程離開同步塊時,會執(zhí)行 monitorexit 指令,釋放對象鎖。
在 AQS 同步中,使用一個 int 類型的變量 state 來表示當前同步塊的狀態(tài)。以獨占式同步(一次只能有一個線程進入同步塊)為例,state 的有效值有兩個 0 和 1,其中 0 表示當前同步塊中沒有線程,1 表示同步塊中已經(jīng)有線程在執(zhí)行。當線程要進入同步塊時,需要首先判斷 state 的值是否為 0,假設為 0,會嘗試將 state 修改為 1,只有修改成功了之后,線程才可以進入同步塊。注意上面提到的兩個條件:
state 為 0,證明當前同步塊中沒有線程在執(zhí)行,所以當前線程可以嘗試獲得進入同步塊的憑證,而這里的憑證就是是否成功將 state 修改為 1(在 synchronized 同步中,我們說的憑證是對象鎖,但是對象