【退役之重學 Java】初步認識 AQS

一、AQS 是什么

  • Abstract Queued Synchronizer ,翻譯過來就是“抽象的排好隊的同步器”。 AQS 是一個用來構建鎖和同步器的框架。
  • 是用來構建鎖或者其他同步器組件的重量級基礎框架及整個JUC體系的基石,通過內置的FIFO隊列來完成線程獲取資源的排隊工作,并通過一個int類型變量表示持有鎖的狀態。

二、AQS 有什么用

  • 使用 AQS 能簡單高效的構造出大量被廣泛應用的同步器,比如 ReentrantLock,Semaphore,ReentrantReadWriteLock,SynchronousQueue,FutureTask等等,都是基于 AQS 的。
  • 我們也可以使用 AQS 輕松構造出符合特定需求的同步器。
  • 加鎖會導致阻塞,有阻塞就需要排隊,實現排隊必然需要有某種形式的隊列(CLH)來進行管理

三、AQS 的核心思想

  • 如果被請求的共享資源空閑,則將當前請求資源的線程設置為有效的工作線程,
  • 并且將共享資源設置為鎖定狀態。
  • 如果被請求的共享資源被占用,那么就需要一套線程阻塞等待以及被喚醒時鎖分配的機制
  • 這個機制是 AQS 使用 CLH隊列鎖實現的,即將暫時獲取不到鎖的線程加入到隊列中。
  • CLH 是一個虛擬的雙向FIFO隊列,AQS 將每個請求共享資源的線程封裝成Node 節點,并放入CLH
  • AQS 使用一個volatile 的 int 類型的變量來表示同步狀態,通過內置的FIFO隊列來完成資源獲取的排隊工作將每條要去搶占資源的線程封裝成一個Node節點來實現鎖的分配,通過CAS完成對State值的修改

四、AQS 基本結構

在這里插入圖片描述

五、AQS 怎么用

  • 創建任一基于AQS實現的同步器
  • 創建多個線程,并分別使用同步器的 lock 和 unlock 方法
  • 會發現,這些線程是一個一個執行的,而非一起執行的,說明鎖成功了。

六、進一步理解鎖和同步器的關系

  • 鎖,面相鎖的使用者,定義了程序員和鎖交互的使用層API
  • 同步器,面相鎖的實現者,

七、源碼分析

  1. Lock --> Syn -----> AQS,所以Lock 最終繼承的是AQS
  2. lock(),acquire(),tryAcquire(arg),addWaiter(Node.EXCLUSIVE),addQueued(addWaiter(Node.EXCLUSIVE),arg)
    在這里插入圖片描述
  3. head和tail
    • 是什么?
      head 和 tail 分別是頭指針和尾指針,分別指向隊列中的頭節點和尾節點
    • 有什么用?
      方便出隊和入隊操作,也方便邏輯判斷(暫時是這么理解的)
  4. 哨兵節點有什么用?
    隊列中的哨兵節點在并發編程中起到了重要的作用。哨兵節點是一種特殊的節點,通常用于幫助管理和控制并發隊列的行為。在使用隊列實現同步器時,哨兵節點可以用來簡化邏輯提高效率確保線程安全
  5. 確實有點復雜,但我感覺不應該去理解源碼的每一行代碼,而應該從整體設計思想去理解就好了,以后有機會自己實現一個簡陋的example。
  6. 出隊操作:第一個真實節點B搶占資源成功,哨兵節點出隊,B變成新的哨兵節點

參考博客 一文讓你徹底搞懂AQS(通俗易懂的AQS)
聲明:僅用于學習,不做其他用途。本文對所引用的博客,進行了摘抄、整理,其中AQS 的知識點并不詳盡,希望未來有機會能夠更加深入地講解它。


擴展

一、可重入鎖

  • 可重入鎖,又名遞歸鎖。是指在同一個線程,在外層方法獲取鎖的時候,再進入線程的內層方法時,會自動獲取鎖(前提,鎖對象得是同一個對象),不會因為之前已經獲取過還沒釋放而阻塞
  • Java 中 ReentrantLock 和 Synchronized 都是可重入鎖
  • 可重入鎖的一個優點是可以一定程度避免死鎖
  • 一句話概括:同一個線程可以多次獲得屬于自己的同一把鎖,一定程度避免死鎖

二、 LockSupport

  1. 是什么
    LockSupport 用于創建鎖和其他同步類的基本線程阻塞原語。
  2. 有什么用
    • 對于原有鎖支持線程等待喚醒機制(wait/nofify)的加強、改良版
    • LockSupport 的 park()和 unpark()的作用分別是阻塞線程和解除阻塞線程
    • 兩個三角形:
      • (synchronized,wait,notify)
      • (lock,await,signal)
  3. 核心思想
    • LockSupport 使用了一種名為 Permit (許可)的概念來做到阻塞和喚醒線程的功能,每個線程都有一個許可(permit),permit 只有兩個值1和0,默認為零
    • 可以把許可看成一種(0,1)信號量(Semaphore),但是與Semaphore 不同的是,許可的累加上限是1
  4. 怎么用
    • LockSupport.park() 阻塞
    • LockSupport.unpark(a) 喚醒啊
    • 什么叫阻塞,什么叫喚醒?
    • 阻塞就是說,在那一步線程就轉換為“等待執行”的狀態
    • 喚醒就是說,讓線程繼續執行
    • unpark()可以在park()之前執行
  5. 優點
    LockSupport 是一個線程阻塞工具類,所有的方法都是靜態方法,可以讓線程在任意位置阻塞,阻塞之后也有對應的喚醒方法。歸根結底,LockSupport 調用 Unsafe 中的native 代碼。
  6. 為什么可以先喚醒線程后阻塞線程?
    因為unpark 獲得了一個憑證,之后,在調用 park 方法,就可以名正言順的憑證消費,故不會阻塞。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/11158.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/11158.shtml
英文地址,請注明出處:http://en.pswp.cn/web/11158.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

centos7時間同步教程

針對問題:在我們使用虛擬機配置好centos7后,發現服務器時間和當前時間對不上 通過命令查看時間不同步 date 或者 date -R修改/etc/sysconfig/clock文件如下內容,保存 vi /etc/sysconfig/clockZONE“Asia/Shanghai” UTCtrue ARCfalse重寫/e…

251 基于matlab的動態粒子群算法

基于matlab的動態粒子群算法。普通粒子群算法無法感知外界環境的變化,在外界環境發生改變時無法實時進行響應,因而缺乏動態環境尋優能力。在普通粒子群算法基本上通過增加敏感粒子得到一種動態粒子群算法,該算法通過實時計算敏感粒子的適應度…

2024年第七屆可再生能源與電力工程國際會議(REPE 2024)即將召開!

2024年第七屆可再生能源與電力工程國際會議(REPE 2024)將于2024年9月25-27日在中國北京召開, 由清華大學主辦。REPE 2024將匯聚國內外知名專家學者通過主旨報告、分組討論和互動交流等形式,分享最新的研究成果、技術進展和應用案例&#xff0…

【教程向】從零開始創建瀏覽器插件(二)深入理解 Chrome 擴展的 manifest.json 配置文件

第二步:深入理解 Chrome 擴展的 manifest.json 配置文件 上一次我們已經著手完成了一個自己的瀏覽器插件,鏈接在這里:我是鏈接 在本篇博客中,我們將更詳細地探討 Chrome 擴展中的 manifest.json 文件。這個文件是每個瀏覽器擴展…

docker容器實現https訪問

前言: 【云原生】docker容器實現https訪問_docker ssl訪問-CSDN博客 一術語介紹 ①key 私鑰 明文--自己生成(genrsa ) ②csr 公鑰 由私鑰生成 ③crt 證書 公鑰 簽名(自簽名或者由CA簽名) ④證書&#xf…

C入門筆記

1. c文件執行過程 C語言程序的執行過程可以分為四個基本步驟:預處理、編譯、匯編和鏈接。下面是這些步驟的簡要概述: 預處理:在這個步驟中,預處理器將源代碼中以 # 開頭的指令進行處理,例如 #include 和 #define。預…

一般社保測試

SI 分析和 PI 分析主要有以下區別: SI 分析: 主要關注信號在傳輸過程中的質量,如信號的失真、反射、串擾等問題。 側重于確保信號的準確傳輸和接收,以實現可靠的數字或模擬信號通信。 PI 分析: 著重于電源分配網絡…

STM32快速入門(定時器之輸出PWM波形)

STM32快速入門(定時器之輸出PWM波形) 前言 本節主要講解STM32利用通用定時器,利用CCR和CNT寄存器,輸出指定占空比和頻率的PWM波形。其功能的應用有:實現LED呼吸燈的效果、控制步進電機、控制直流電機轉速等。 導航 …

Java 類加載過程

什么是類加載 Java 類加載是指將 Java 字節碼文件加載到 Java 虛擬機(JVM)中,并將其轉化為可以執行的可執行代碼的過程。當 Java 程序在運行時引用某個類時,JVM 會首先檢查是否已經加載該類,如果沒有加載,則…

ue5地編模塊學習記錄

ue5網站功能3d溜溜網下載模型https://anyconv.com/max-to-fbx-converter/3dmax轉換fbx模型解決問題記錄 一、光源 搜索光源搜索不到的時候可以點擊 窗口> 對場景內的光照進行處理

【Java】數組訓練案例

訓練案例1 需求描述: 定義一個含有五個元素的數組,并為每個元素賦值,求數組中所有元素的最小值。 操作步驟描述: 1) 定義5個元素數組。 2) 可以使用初始化數組的兩種方式之一為數組元素賦值。 3&#xff09…

最佳解決Maven同一依賴多版本共存問題,重復依賴(同一個jar包,多個版本)-maven-shade-plugin

先看鏈接:原文鏈接 參照原文鏈接生成的文件(下面是我放的位置) mvn指令 mvn install:install-file -DfileD:\mavenrepository/maven-shade.jar -DgroupIdcom.wj -DartifactIdmaven-shade -Dversion1.1 -Dpackagingjar如果配置了maven_home 和java_home可以任意打開cmd執行(…

Google: 在新知識上微調大語言模型是否會鼓勵產生幻覺?

摘要 當大型語言模型通過監督式微調進行對齊時,它們可能會遇到在預訓練期間沒有獲得的新事實信息。人們經常推測,這可能會教導模型產生事實上不正確的回應的行為,因為模型被訓練成生成沒有基于其預先存在的知識的事實。在這項工作中,Google研究了這種暴露在新知識下對微調后模…

基于springboot實現高校教師電子名片系統項目【項目源碼+論文說明】計算機畢業設計

基于springboot實現高校教師電子名片系統演示 摘要 傳統信息的管理大部分依賴于管理人員的手工登記與管理,然而,隨著近些年信息技術的迅猛發展,讓許多比較老套的信息管理模式進行了更新迭代,名片信息因為其管理內容繁雜&#xff…

C++的數據結構(五):樹和存儲結構及示例

在計算機科學中,樹是一種抽象數據類型(ADT)或是實現這種抽象數據類型的數據結構,用來模擬具有樹狀結構性質的數據集合。這種數據結構以一系列連接的節點來形成樹形結構。在C中,樹的概念和存儲結構是實現各種復雜算法和…

Java--初識類和對象

前言 本篇講解Java類和對象的入門版本。 學習目的: 1.理解什么是類和對象。 2.引入面向對象程序設計的概念 3.學會如何定義類和創建對象。 4.理解this引用。 5.了解構造方法的概念并學會使用 考慮到篇幅過長問題,作者決定分多次發布。 面向對象的引入 J…

Docker之grep: (standard input): binary file matches

使用 docker compose logs -f | grep 命令時遇到了 grep: (standard input): binary file matches 錯誤。 這個錯誤通常發生在 grep 嘗試搜索包含二進制內容的文件時。docker compose logs 命令會輸出容器的日志,而這些日志可能包含二進制數據,導致 gre…

MySQL查詢篇-集合運算

文章目錄 union (并集)union distinctunion all intersect(交集)intersect allintersect distinct except 差集except distinctexcept distinctexcept all union (并集) union distinct 使用前提:a和c數據類型一致&a…

互聯網摸魚日報(2024-05-13)

互聯網摸魚日報(2024-05-13) 36氪新聞 當綠色飛行成為潮流,這家航空公司定下了新目標 | 最前線 回收雨水澆花,廚余垃圾變肥料,我們打卡了阿里北京新園區 | 最前線 本周雙碳大事:中美就氣候問題進行會談;鋰電池行業迎…

GIAT: 蛋白質結構預測的新利器

瑞典Karolinska研究院在瑞典政府贊助下由Ben Murrell等研究團隊在AlphaFold 3最新報告后提出這篇論文提出了一種非常有趣和創新的方法來生成蛋白質骨架結構,稱為生成式不變角度轉換器(GIAT)。與現有的主要基于擴散模型和流匹配的方法不同,GIAT采用了類似于大型語言模型(如GPT)中…