什麼是AQS ?

AQS( AbstractQueuedSynchronizer 類 ) 是 一 個 用 來 構 建 鎖 和 同 步 器
的 框 架 , 各 種  Lock  包 中 的 鎖 ( 常 用 的 有  ReentrantLock、
ReadWriteLock) , 以 及 其 他 如  Semaphore、 CountDownLatch, 甚
至 是 早 期 的 FutureTask 等 , 都 是 基 於 AQS 來 構 建 。
1.  AQS 在 內 部 定 義 了 一 個 volatile int state 變 量 , 表 示 同 步 狀 態 : 當 線
程 調 用 lock 方 法 時 , 如 果 state=0, 說 明 沒 有 任 何 線 程 佔 有 共 享 資 源
的 鎖 , 可 以 獲 得 鎖 並 將 state=1; 如 果 state=1, 則 說 明 有 線 程 目 前 正 在
使 用 共 享 變 量 , 其 他 線 程 必 須 加 入 同 步 隊 列 進 行 等 待 。
2.  AQS 通 過 Node 內 部 類 構 成 的 一 個 雙 向 鏈 表 結 構 的 同 步 隊 列 , 來 完 成 線
程 獲 取 鎖 的 排 隊 工 作 , 當 有 線 程 獲 取 鎖 失 敗 後 , 就 被 添 加 到 隊 列 末 尾 。
o Node  類 是 對 要 訪 問 同 步 代 碼 的 線 程 的 封 裝 , 包 含 了 線 程 本 身 及 其 狀 態 叫
waitStatus( 有 五 種 不 同  取 值 , 分 別 表 示 是 否 被 阻 塞 , 是 否 等 待 喚 醒 ,
是 否 已 經 被 取 消 等 ) , 每 個 Node 結 點 關 聯 其 prev 結 點 和 next 結
點 , 方 便 線 程 釋 放 鎖 後 快 速 喚 醒 下 一 個 在 等 待 的 線 程 , 是 一 個 FIFO 的 過
程 。
o Node 類 有 兩 個 常 量 , SHARED 和 EXCLUSIVE, 分 別 代 表 共 享 模 式 和 獨
佔 模 式 。 所 謂 共 享 模 式 是 一 個 鎖 允 許 多 條 線 程 同 時 操 作 ( 信 號 量
Semaphore 就 是 基 於 AQS 的 共 享 模 式 實 現 的 ) , 獨 佔 模 式 是 同 一 個 時
間 段 只 能 有 一 個 線 程 對 共 享 資 源 進 行 操 作 , 多 餘 的 請 求 線 程 需 要 排 隊 等 待
( 如 ReentranLock) 。
3.  AQS  通 過 內 部 類  ConditionObject  構 建 等 待 隊 列 ( 可 有 多 個 ) , 當
Condition  調 用  wait()  方 法 後 , 線 程 將 會 加 入 等 待 隊 列 中 , 而 當
Condition 調 用 signal() 方 法 後 , 線 程 將 從 等 待 隊 列 轉 移 動 同 步 隊 列 中
進 行 鎖 競 爭 。
4.  AQS  和  Condition  各 自 維 護 了 不 同 的 隊 列 , 在 使 用  Lock  和
Condition 的 時 候 , 其 實 就 是 兩 個 隊 列 的 互 相 移 動 。
問 題 三 : 請 盡 可 能 詳 盡 地 對 比 下  Synchronized  和  ReentrantLock
的 異 同 。
ReentrantLock 是 Lock 的 實 現 類 , 是 一 個 互 斥 的 同 步 鎖 。
從 功 能 角 度 , ReentrantLock  比  Synchronized  的 同 步 操 作 更 精 細
( 因 爲 可 以 像 普 通 對 象 一 樣 使 用 ) , 甚 至 實 現  Synchronized  沒 有 的
高 級 功 能 , 如 :
 等 待 可 中 斷 : 當 持 有 鎖 的 線 程 長 期 不 釋 放 鎖 的 時 候 , 正 在 等 待 的 線 程 可
以 選 擇 放 棄 等 待 , 對 處 理 執 行 時 間 非 常 長 的 同 步 塊 很 有 用 。
 帶 超 時 的 獲 取 鎖 嘗 試 : 在 指 定 的 時 間 範 圍 內 獲 取 鎖 , 如 果 時 間 到 了 仍 然
無 法 獲 取 則 返 回 。
 可 以 判 斷 是 否 有 線 程 在 排 隊 等 待 獲 取 鎖 。
 可 以 響 應 中 斷 請 求 : 與  Synchronized  不 同 , 當 獲 取 到 鎖 的 線 程 被 中
斷 時 , 能 夠 響 應 中 斷 , 中 斷 異 常 將 會 被 拋 出 , 同 時 鎖 會 被 釋 放 。
 可 以 實 現 公 平 鎖 。
從 鎖 釋 放 角 度 , Synchronized 在 JVM 層 面 上 實 現 的 , 不 但 可 以 通 過
一 些 監 控 工 具 監 控  Synchronized  的 鎖 定 , 而 且 在 代 碼 執 行 出 現 異 常
時 , JVM 會 自 動 釋 放 鎖 定 ; 但 是 使 用 Lock 則 不 行 , Lock 是 通 過 代
碼 實 現 的 , 要 保 證 鎖 定 一 定 會 被 釋 放 , 就 必 須 將  unLock()  放 到
finally{} 中 。
從 性 能 角 度 , Synchronized  早 期 實 現 比 較 低 效 , 對 比
ReentrantLock, 大 多 數 場 景 性 能 都 相 差 較 大 。
但 是 在  Java  6  中 對 其 進 行 了 非 常 多 的 改 進 , 在 競 爭 不 激 烈 時 ,
Synchronized  的 性 能 要 優 於  ReetrantLock; 在 高 競 爭 情 況 下 ,
Synchronized 的 性 能 會 下 降 幾 十 倍 , 但 是 ReetrantLock 的 性 能 能 維
持 常 態 。

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