ReentrantLock 實現公平鎖和非公平鎖的原理!

在這里插入圖片描述

🌟我的其他文章也講解的比較有趣😁,如果喜歡博主的講解方式,可以多多支持一下,感謝🤗!

🌟了解 ThreadLocal請看: ThreadLocal有趣講解,小白也能聽懂!

其他優質專欄: 【🎇SpringBoot】【🎉多線程】【🎨Redis】【?設計模式專欄(已完結)】…等

如果喜歡作者的講解方式,可以點贊收藏加關注,你的支持就是我的動力
?更多文章請看個人主頁: 碼熔burning

想象一下,有一個很受歡迎的公共廁所 🚽,同一時間只能一個人進去。

ReentrantLock 就好比是這個廁所的門鎖管理員。他負責管理誰能進去。

深入了解 ReentrantLock 請看:ReentrantLock:可定制的“VIP 包間”

核心原理:AQS

ReentrantLock 的底層依賴一個叫做 AQS 的框架。你可以把 AQS 理解為一個通用的排隊和狀態管理系統

  1. 狀態 (State): AQS 內部有一個 state 變量(是個整數)。在 ReentrantLock 里:
    • state = 0: 表示廁所現在沒人,門是空閑的 ?。
    • state > 0: 表示廁所有人,門被占用了 🔒。這個數字還表示同一個人重復進入(重入)了多少次。比如一個人進去后,又在里面鎖了一層門,state 就變成 2。
  2. 等待隊列 (Queue): AQS 維護了一個等待隊列。這個隊列像銀行排隊的隊伍一樣,是先進先出 (FIFO) 的 🚶?♂?🚶?♀?🚶?♂?。想上廁所但發現里面有人的人(線程),就會被安排到這個隊列里排隊等著。

非公平鎖 (Nonfair Lock) - 默認模式

  • 解釋: 就像一個秩序不太好的廁所。
    • 當你(線程)想上廁所時,你首先會沖到門口 🏃💨,猛地推一下門,看看是不是正好沒人(嘗試用 CAS 原子操作直接把 state 從 0 改成 1)。
    • 如果正好沒人,恭喜你 🎉,你直接就進去了!哪怕旁邊已經有人在排隊等了很久,你也可能因為動作快而“插隊”成功。
    • 如果里面有人(推門失敗,state 不是 0),或者你嘗試搶鎖的那一下正好別人也搶成功了,那你沒辦法 😟,只能乖乖去隊伍(AQS 隊列)后面排著
    • 當里面的人出來(釋放鎖)時,管理員(AQS)會喚醒 ? 隊伍最前面的人。但是,與此同時,如果又有一個新人跑過來直接推門 🏃💨,并且正好成功了,那這個剛被喚醒、正準備進去的人可能又得等一下。
  • 底層實現關鍵點:
    • 調用 lock() 時,先嘗試直接獲取鎖(CAS 修改 state)。
    • 獲取失敗,才把自己加入 AQS 等待隊列。
    • 釋放鎖時,喚醒隊頭節點,但新來的線程仍有機會搶先獲取鎖
  • 優點: 可能性能更好,吞吐量更高 🚀。因為減少了線程掛起和喚醒的次數(如果運氣好直接搶到鎖,就不用排隊和被喚醒了)。
  • 缺點: 可能導致饑餓 😩。排在前面的線程可能一直等不到鎖,因為總有新來的線程“插隊”成功。

公平鎖 (Fair Lock)

  • 解釋: 就像一個非常有秩序的廁所 👍。
    • 當你(線程)想上廁所時,你首先會看一眼 👀 隊伍前面有沒有人排隊 (hasQueuedPredecessors() 檢查)。
    • 如果隊伍里有人,對不起 🙅?♂?,你不能直接去推門,必須老老實實去隊伍(AQS 隊列)后面排著 🚶?♂?🚶?♀?。
    • 只有當隊伍是空的,你才可以去嘗試推門(嘗試 CAS 修改 state)。
    • 當里面的人出來(釋放鎖)時,管理員(AQS)只會喚醒隊伍最前面的那個人,并且只有這個人能進去。新來的人?對不起,看隊伍里有人,請自覺排隊。
  • 底層實現關鍵點:
    • 調用 lock() 時,先檢查 AQS 隊列中是否有等待者
    • 如果有等待者,則不嘗試獲取鎖,直接加入隊列尾部。
    • 只有當隊列為空時,才嘗試獲取鎖。
    • 釋放鎖時,嚴格喚醒并讓隊頭節點獲取鎖
  • 優點: 公平 ??,保證了先來后到,不會有線程餓死。
  • 缺點: 性能相對較低,吞吐量可能不如非公平鎖 📉。因為即使鎖是空閑的,只要隊列里有人,新來的線程也得去排隊,導致更多的線程掛起和喚醒,增加了上下文切換的開銷。

總結一下 ??:

ReentrantLock 通過內部的 Sync 類(它繼承了 AQS)來實現鎖邏輯 🛠?。Sync 有兩個子類:NonfairSyncFairSync

  • 核心區別在于嘗試獲取鎖 (tryAcquire 方法) 時的行為:
    • NonfairSync: 直接嘗試 CAS 修改 state,失敗再入隊。
    • FairSync: 先檢查隊列是否為空或者自己是不是隊頭,滿足條件才嘗試 CAS 修改 state,否則直接入隊。

🤔 默認情況下,new ReentrantLock() 創建的是非公平鎖,因為它通常有更好的性能。如果你需要保證公平性,可以使用 new ReentrantLock(true) 來創建公平鎖

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

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

相關文章

NLP高頻面試題(四十一)——什么是 IA3 微調?

隨著大型語言模型的廣泛應用,如何高效地將這些模型適配到特定任務中,成為了研究和工程實踐中的重要課題。IA3(Infused Adapter by Adding and Adjusting)微調技術,作為參數高效微調的一種新穎方法,提供了在保持模型性能的同時,顯著減少可訓練參數數量的解決方案。 IA3 …

swift菜鳥教程14(閉包)

一個樸實無華的目錄 今日學習內容:1.Swift 閉包1.1閉包定義1.2閉包實例1.3閉包表達式1.3.1sorted 方法:據您提供的用于排序的閉包函數將已知類型數組中的值進行排序。1.3.2參數名稱縮寫:直接通過$0,$1,$2來順序調用閉包的參數。1.3.3運算符函…

藍橋杯-藍橋幼兒園(Java-并查集)

并查集的核心思想 并查集主要由兩個操作構成: Find:查找某個元素所在集合的根節點。并查集的特點是,每個元素都指向它自己的父節點,根節點的父節點指向它自己。查找過程中可以通過路徑壓縮來加速后續的查找操作,即將路…

ruby內置全局變量

以下是 Ruby 中常見的 內置全局變量 及其用途的詳細說明。這些變量以 $ 開頭,由 Ruby 解釋器自動管理,用于訪問系統狀態、異常、輸入輸出等核心信息。 一、異常處理相關 全局變量說明示例$!當前作用域最后拋出的異常對象(等同于 rescue >…

tcp轉串口

windows 在 Windows 系統上,可以使用以下成熟的串口轉 TCP 工具: HW VSP3 (HW Virtual Serial Port) 提供串口到 TCP/IP 的映射功能。支持虛擬串口和網絡通信。下載地址:HW Group com0com com2tcp 開源工具,支持虛擬串口和 TCP…

HTML視頻和音頻

<video>元素 <video>元素用于在HTML文檔中嵌入視頻內容。 <video controls><source src"movie.mp4" type"video/mp4"><source src"movie.ogg" type"video/ogg">您的瀏覽器不支持 HTML5 video 標簽。 …

DeepSeek:重構辦公效率的AI新范式

目錄 一、效率躍遷的三重引擎 二、效率提升的量級突破 三、智能辦公的范式轉移 四、未來辦公的效率奇點 當企業主面對堆積如山的文件審批、跨時區協作的溝通損耗、重復機械的數據整理時&#xff0c;是否想過這些場景正在吞噬團隊的生產力&#xff1f;據麥肯錫研究顯示&…

redis 延遲雙刪

Redis延遲雙刪是一種用于解決緩存與數據庫數據一致性問題的策略&#xff0c;通常在高并發場景下使用。以下是其核心內容&#xff1a; 1. 問題背景 當更新數據庫時&#xff0c;如果未及時刪除或更新緩存&#xff0c;可能導致后續讀請求仍從緩存中讀取舊數據&#xff0c;造成數…

Python設計模式:策略模式

1. 什么是策略模式 策略模式&#xff08;Strategy Pattern&#xff09;是一種行為型設計模式&#xff0c;它定義了一系列算法&#xff0c;將每個算法封裝起來&#xff0c;并使它們可以互換。策略模式使得算法的變化獨立于使用算法的客戶。換句話說&#xff0c;策略模式允許在運…

SpringBoot集成Ollama本地模型

SpringBoot集成Ollama本地模型 目錄 項目準備創建Ollama服務客戶端創建控制器配置應用屬性創建前端界面添加靜態資源支持完整項目結構啟動應用高級功能擴展部署注意事項性能優化 1. 項目準備 創建一個SpringBoot項目&#xff0c;可以使用Spring Initializr或IDE創建添加必要…

ResNet改進(19):基于PyTorch的ResNet改進方案詳解:Mish激活+SPP模塊+MixUp數據增強

1. 前言 ResNet作為深度學習領域里程碑式的網絡架構,在圖像分類等計算機視覺任務中表現出色。然而,隨著研究的深入和技術的發展,原始的ResNet架構仍有改進空間。本文將詳細介紹一種基于PyTorch的ResNet改進方案,該方案融合了Mish激活函數、SPP模塊和MixUp數據增強等先進技…

leetcode68.左右文本對齊

思路源自 leetcode-字符串篇 68題 文本左右對齊 難度高的模擬類型題目&#xff0c;關鍵點在于事先知道有多少單詞要放在本行并且還要知道本行是不是最后一行&#xff08;最后一行需要全部單空格右對齊&#xff0c;不是最后一行就空格均攤&#xff09;&#xff0c;非最后一行的空…

深入理解 Spring 的 MethodParameter 類

MethodParameter 是 Spring 框架中一個非常重要的類&#xff0c;它封裝了方法參數&#xff08;或返回類型&#xff09;的元數據信息。這個類在 Spring MVC、AOP、數據綁定等多個模塊中都有廣泛應用。 核心功能 MethodParameter 主要提供以下功能&#xff1a; 獲取參數類型信息…

Qt 5.14.2入門(一)寫個Hello Qt!程序

目錄 參考鏈接&#xff1a;一、新建項目二、直接運行三、修改代碼增加窗口內容1、Qt 顯示一個 QLabel 標簽控件窗口2、添加按鍵 參考鏈接&#xff1a; Qt5教程&#xff08;一&#xff09;&#xff1a;Hello World 程序 Qt 編程指南 一、新建項目 1、新建一個項目&#xff08…

Spring Boot 3.x 集成 MongoDB 的 默認配置項及默認值,以及 常用需要修改的配置項 的詳細說明

以下是 Spring Boot 3.x 集成 MongoDB 的 默認配置項及默認值&#xff0c;以及 常用需要修改的配置項 的詳細說明&#xff1a; 一、默認配置項及默認值 Spring Boot 對 MongoDB 的默認配置基于 spring.data.mongodb 前綴&#xff0c;以下是核心配置項&#xff1a; 配置項默認…

【QT】 進程

目錄 QT 多進程復習 Linux-C 多進程QProcess 進程類常用方法簡單示例信號與槽應用場景 跨平臺注意事項技巧&#xff1a;使用宏控制平臺命令 QProcess 在嵌入式系統中的使用示例&#xff1a;調用 ALSA 播放音頻示例&#xff1a;調用 arecord 錄音示例&#xff1a;QProcess Shel…

原子操作(cpp atomic)

目錄 一.原子操作 1.原子操作的概念 2.原子變量 二.原子性 1.中間狀態描述 2.單處理器單核 3.多處理器或多核的情況下 4.cache&#xff08;高速緩沖器的作用&#xff09; 5.在cpu cache基礎上,cpu如何讀寫數據&#xff1f;&#xff1f;&#xff1f; 6.為什么會有緩存…

Unet網絡的Pytorch實現和matlab實現

文章目錄 一、Unet網絡簡介1.1 輸入圖像1.2 編碼器部分&#xff08;Contracting Path&#xff09;1.3 解碼器部分&#xff08;Expanding Path&#xff09;1.4 最后一層&#xff08;輸出&#xff09;1.5 跳躍連接&#xff08;Skip Connections&#xff09; 二、Unet網絡的Pytorc…

記錄一次JVM調優過程1

如何通過jmap 診斷&#xff0c;服務運行一段時間后內存使用量飆升的問題 通過 jmap 診斷服務運行一段時間后內存使用量飆升的問題&#xff0c;需結合堆轉儲分析、對象分布統計及工具鏈配合。以下是具體操作步驟和關鍵方法&#xff1a; 一、實時監控與初步分析 獲取進程 PID 使…

接口自動化學習五:mock工具使用

Moco簡介&#xff1a; Mock是一個簡單搭建模擬服務器的框架&#xff0c;可以用來模擬http、https、socket等協議。 原理&#xff1a; Mock會根據一些配置&#xff0c;啟動一個真正的HTTP服務&#xff08;會監聽本地的某個端口&#xff09;,當發起的請求滿足某個條件時&#xf…