深入理解Redission釋放鎖過程

lock.unlock();

調用unlock方法,往下追

@Override
public void unlock() {try {// 1. 執行異步解鎖操作并同步等待結果// - 獲取當前線程ID作為鎖持有者標識// - unlockAsync()觸發Lua腳本執行實際解鎖// - get()方法阻塞直到異步操作完成get(unlockAsync(Thread.currentThread().getId()));} catch (RedisException e) {// 2. 異常處理:識別非法解鎖場景if (e.getCause() instanceof IllegalMonitorStateException) {// 2.1 特殊處理:當前線程非鎖持有者// - 通常在Lua腳本返回nil時觸發// - 表示嘗試釋放未被當前線程持有的鎖throw (IllegalMonitorStateException) e.getCause();} else {// 2.2 其他Redis異常(如連接問題)// - 網絡中斷、Redis宕機等場景throw e;}}// 3. 成功執行路徑://   - Lua腳本返回0(重入鎖部分釋放)或1(完全釋放)//   - 后臺自動觸發看門狗任務取消(完全釋放時)
}

再往下追unlcokAsync這個異步方法
這里調用解鎖方法unlockInnerAsync同樣返回了RFutrue,當lua腳本執行完過后,RFutrue就會變成完成狀態,回調用回調函數onComplete,lua腳本就是再unlockInnerAsync里執行的,我們接著往下追

@Override
public RFuture<Void> unlockAsync(long threadId) {// 創建異步結果對象,用于返回解鎖操作最終狀態RPromise<Void> result = new RedissonPromise<Void>();// 執行核心解鎖操作(發送Lua腳本到Redis)RFuture<Boolean> future = unlockInnerAsync(threadId);// 注冊回調函數處理解鎖結果future.onComplete((opStatus, e) -> {// 關鍵步驟:無論解鎖成功與否,都取消看門狗續期任務// 防止鎖釋放后繼續續期(相當于"喂狗"操作停止)cancelExpirationRenewal(threadId);// 異常處理:Redis操作出錯if (e != null) {result.tryFailure(e);  // 設置結果為失敗并傳遞異常return;}// 非法狀態檢查:opStatus為null表示解鎖失敗// 常見原因:嘗試釋放非當前線程持有的鎖if (opStatus == null) {// 構造詳細的非法狀態異常信息IllegalMonitorStateException cause = new IllegalMonitorStateException("attempt to unlock lock, not locked by current thread by node id: "+ id + " thread-id: " + threadId);result.tryFailure(cause);  // 設置結果為失敗return;}// 解鎖成功:設置結果為成功result.trySuccess(null);});// 返回異步結果對象return result;
}
protected RFuture<Boolean> unlockInnerAsync(long threadId) {return evalWriteAsync(getName(), LongCodec.INSTANCE, RedisCommands.EVAL_BOOLEAN,-- 1. 驗證鎖持有者身份
if (redis.call('hexists', KEYS[1], ARGV[3]) == 0) then return nil;  -- 非持有者嘗試解鎖
end; -- 2. 減少重入計數
local counter = redis.call('hincrby', KEYS[1], ARGV[3], -1); -- 3. 判斷是否完全釋放
if (counter > 0) then -- 3.1 未完全釋放(重入場景)redis.call('pexpire', KEYS[1], ARGV[2]);  -- 更新過期時間return 0;  -- 返回未完全釋放標識
else -- 3.2 完全釋放redis.call('del', KEYS[1]);  -- 刪除鎖redis.call('publish', KEYS[2], ARGV[1]);  -- 發布解鎖消息return 1;  -- 返回成功釋放標識
end; return nil;  -- 默認返回(不會執行到這里)Arrays.asList(getName(), getChannelName()), LockPubSub.UNLOCK_MESSAGE, internalLockLeaseTime, getLockName(threadId));}

?再執行完過后回取消定時任務,我們追進去,這里設計到全局靜態map EXPIRATION_RENEWAL_MAP 放一張流程圖方便回憶這個map

void cancelExpirationRenewal(Long threadId) {// 從全局MAP獲取EntryExpirationEntry entry = EXPIRATION_RENEWAL_MAP.get(getEntryName());if (entry != null) {// 關鍵操作:移除線程記錄entry.removeThreadId(threadId);// 檢查是否完全釋放if (entry.hasNoThreads()) {// 取消定時任務Timeout timeout = entry.getTimeout();if (timeout != null) {timeout.cancel();}// 從全局MAP移除EXPIRATION_RENEWAL_MAP.remove(getEntryName());}}
}

可以看到map存儲的是鎖的名稱和entry對象 entry對象里面放入了線程id,所以釋放的時候先從entry移除線程id,如果沒有了線程id再從map里移除entry對象

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

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

相關文章

四、計算機組成原理——第4章:指令系統

目錄 4.1指令系統 4.1.1指令集體系結構 4.1.2指令的基本格式 1.零地址指令 2.一地址指令 3.二地址指令 4.三地址指令 5.四地址指令 4.1.3定長操作碼指令格式 4.1.4擴展操作碼指令格式 4.1.5指令的操作類型 1.數據傳送 2.算術和邏輯運算 3.移位操作 4.轉移操作 …

RAG面試內容整理-檢索器與生成器的解耦架構

在RAG系統中,檢索器(Retriever)與生成器(Generator)的解耦架構是實現靈活高效的關鍵設計。所謂解耦,即將檢索相關文檔和生成答案兩個步驟分開,由不同的模塊或模型負責。這種架構帶來的直接好處是模塊獨立優化:我們可以針對檢索任務微調或更換檢索模型,而不必影響生成模…

【2026畢業論文鴻蒙系統畢設選題】最新穎的基于HarmonyOS鴻蒙畢業設計選題匯總易過的精品畢設項目分享(建議收藏)?

文章目錄前言最新畢設選題&#xff08;建議收藏起來&#xff09;最新穎的鴻蒙畢業設計選題匯總100套易過的精品畢設項目分享畢設作品推薦&#x1f447;&#x1f447;&#x1f447;文未可免費咨詢畢設相關問題&#xff0c;點贊留言可送系統源碼&#x1f447;&#x1f447;&#…

超全!Linux 面試 100 題精選解析:網絡篇|16 個 Linux 網絡排查與配置必考題詳解

網絡&#xff0c;是 Linux 系統的神經系統。 一臺服務器再強大&#xff0c;沒有網絡連接也如孤島。尤其在實際運維與面試場景中&#xff0c;“網絡相關的問題”是高頻重災區&#xff0c;比如&#xff1a; IP 配置錯亂&#xff0c;連不上公網DNS 無響應&#xff0c;域名解析失敗…

在 CentOS 上安裝 FFmpeg

在 CentOS 上安裝 FFmpeg 可以通過以下兩種推薦方法實現&#xff08;以 CentOS 7/8 為例&#xff09;&#xff1a; 方法一&#xff1a;通過 RPM Fusion 倉庫安裝&#xff08;推薦&#xff09; # 1. 安裝 EPEL 倉庫 sudo yum install epel-release# 2. 啟用 RPM Fusion 倉庫 # C…

數據結構——圖(一、圖的定義)

一、圖的定義1、什么是圖&#xff1f;圖G(V,E) 如圖&#xff0c;無向圖G頂點集V{,,...,}&#xff0c;用|V|表示圖G的頂點個數如&#xff1a;V{A,B,C,D} ,|V|4邊集E{(u,v)|uV, vV}&#xff0c; 用|E|表示圖G的邊的條數如&#xff1a;E{(u,v)|(A,B),(A,D),(A,C),(C,D)}&#xf…

Python 列表推導式與生成器表達式

Python 列表推導式與生成器表達式在 Python 中&#xff0c;列表推導式&#xff08;List Comprehension&#xff09;和生成器表達式&#xff08;Generator Expression&#xff09;是處理序列數據的高效工具。它們不僅能簡化代碼&#xff0c;還能提升數據處理的效率。本文將詳細介…

XCF32PVOG48C Xilinx Platform Flash PROM

XCF32PVOG48C 是 Xilinx 公司推出的一款高容量、低功耗的 Platform Flash PROM&#xff08;平臺閃存配置芯片&#xff09;&#xff0c;專為 Xilinx FPGA 和 CPLD 系列產品提供非易失性配置存儲支持。憑借其 32 Mbit 的大容量與出色的系統兼容性&#xff0c;該芯片成為中高端 FP…

重復文件清理工具,附免費鏈接

鏈接:https://pan.baidu.com/s/1s_Zx1eHp5Y-XnbbGldIgvw?pwdkjex 提取碼:kjex 復制這段內容后打開百度網盤手機App&#xff0c;操作更方便哦

【Spring Boot 快速入門】二、請求與響應

目錄請求響應請求Postman 工具簡單參數請求實體參數請求數組集合參數日期參數JSON 參數路徑參數響應請求響應 請求 Postman 工具 Postman 是一款功能強大的網頁調試與發送網頁 HTTP 請求的 Chrome 插件 作用&#xff1a;常用于進行接口測試 簡單參數請求 原始方式 在原始的…

高并發系統技術架構

&#xff08;點個贊&#xff0c;算法會給你推薦更多類似干貨 ~&#xff09; 口訣&#xff1a; CDN 扛靜態&#xff0c;WAF 防惡意&#xff1b;驗證碼攔機器&#xff1b; Nginx 先限流&#xff0c;Sentinel 再熔斷&#xff1b; Redis 扣庫存&#xff0c;MQ 異步寫&#xff1b; 對…

python任意模塊間采用全局字典來實現借用其他類對象的方法函數來完成任務或數據通信的功能

我們在編寫pthon代碼時&#xff0c;模塊間的數據通信主要采用以下幾種方法&#xff1a;1、采用全局變量。所有模塊都通過引用全局變量&#xff0c;通過本模塊對此全局變量數據的修改值&#xff0c;其他模塊也能訪問并得到此全局變量的當前值&#xff0c;由于全局變量的不可控性…

linux 部署 flink 1.15.1 并提交作業

下載 1.15.1 https://flink.apache.org/downloads.html#apache-flink-1151 部署模式分類 會話模式應用模式單作業模式 1、會話模式 先啟動一個集群&#xff0c;保持一個會話&#xff0c;然后通過客戶端提交作業&#xff0c;所有作業都在一個會話執行&#xff1b; 會話模式適合規…

Redis數據量過大的隱患:查詢會變慢嗎?如何避免?

一、Redis數據過多引發的五大隱患&#xff08;附系統交互圖&#xff09; #mermaid-svg-X83bpHUu830QXKUt {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-X83bpHUu830QXKUt .error-icon{fill:#552222;}#mermaid-svg-…

網絡與信息安全有哪些崗位:(3)安全運維工程師

安全運維工程師是企業安全防線的 “日常守護者”&#xff0c;既要確保安全設備與系統的穩定運行&#xff0c;又要實時監控潛在威脅&#xff0c;快速響應并處置安全事件&#xff0c;是連接安全技術與業務運營的關鍵角色。其核心價值在于通過常態化運維&#xff0c;將安全風險控制…

魚皮項目簡易版 RPC 框架開發(三)

本文為筆者閱讀魚皮的項目 《簡易版 RPC 框架開發》的筆記&#xff0c;如果有時間可以直接去看原文&#xff0c; 1. 簡易版 RPC 框架開發 前面的內容可以筆者的前面兩個篇筆記 魚皮項目簡易版 RPC 框架開發&#xff08;一&#xff09; 魚皮項目簡易版 RPC 框架開發&#xff08;…

嵌入式Linux:注冊線程清理處理函數

在 Linux 多線程編程中&#xff0c;線程終止時可以執行特定的清理操作&#xff0c;通過注冊線程清理函數&#xff08;thread cleanup handler&#xff09;來實現。這類似于使用 atexit() 注冊進程終止處理函數。線程清理函數用于在線程退出時執行一些資源釋放或清理工作&#x…

【Git】Linux-ubuntu 22.04 初步認識 -> 安裝 -> 基礎操作

文章目錄Git 初識Git 安裝Linux-centosLinux-ubuntuWindowsGit 基本操作配置 Git認識工作區、暫存區、版本庫添加文件 -- 場景一查看 .git 文件添加文件 -- 場景二修改文件版本回退撤銷修改情況一&#xff1a;對于工作區的代碼&#xff0c;還沒有 add情況二&#xff1a;已經 ad…

輕量級音樂元數據編輯器Metadata Remote

簡介 什么是 Metadata Remote (mdrm) &#xff1f; Metadata Remote 是一個基于 Web 的音頻元數據編輯工具&#xff0c;旨在簡化在無頭服務器&#xff08;即沒有圖形用戶界面的服務器&#xff09;上編輯音頻文件的元數據。用戶只需使用 Docker 和瀏覽器&#xff0c;無需復雜的…

免費使用|共享服務器上線RTX3080(20GB顯存)

共享服務器也上架GPU啦 生物信息學中有很多用到GPU的場景&#xff0c;例如我們分享過的&#xff1a;利用GPU加速TensorFlow、部署本地DeepSeek&#xff0c;空間轉錄組學習手冊合輯加速。因此多種GPU供大家選擇&#xff1a;RTX5090、4080S、5070顯卡上機。為了讓此前的CPU服務器…