Java并發編程 什么是分布式鎖 跟其他的鎖有什么區別 底層原理 實戰講解

目錄

一、分布式鎖的定義與核心作用

二、分布式鎖與普通鎖的核心區別

三、分布式鎖的底層原理與實現方式

1. 核心實現原理

2. 主流實現方案對比

3. 關鍵技術細節

四、典型問題與解決方案

五、總結

六、具體代碼實現


一、分布式鎖的定義與核心作用

分布式鎖是一種在分布式系統中協調多進程/節點對共享資源進行互斥訪問的機制。其核心作用是確保同一時間只有一個進程能夠操作共享資源,解決分布式環境下的并發沖突問題(如超賣、數據覆蓋等)。


二、分布式鎖與普通鎖的核心區別

對比維度

普通鎖(線程/進程鎖)

分布式鎖

作用范圍

單機環境(同一JVM或進程內)

跨機器、跨JVM的分布式環境

數據存儲

基于內存(如synchronized、Lock)

基于外部存儲(如Redis、ZooKeeper、數據庫)

鎖失效風險

無網絡延遲或節點故障風險

需處理網絡分區、節點宕機、時鐘同步等問題

典型應用場景

單機多線程資源競爭

分布式服務、微服務集群、數據庫流量控制等


三、分布式鎖的底層原理與實現方式

1. 核心實現原理
  • 互斥性:通過唯一標識(如Redis的Key、ZooKeeper節點路徑)確保同一時間僅有一個客戶端持有鎖。
  • 超時機制:設置鎖的過期時間,避免死鎖(如Redis的PX參數)。
  • 原子性操作:加鎖、解鎖需通過原子命令(如Redis的SETNX+EXPIRE組合或Lua腳本)實現。
2. 主流實現方案對比

實現方式

原理

優點

缺點

Redis

基于SET key value NX PX

命令,結合唯一值(UUID)和Lua腳本保證原子性 。

高性能、易擴展

主從切換可能導致鎖失效(需RedLock或Redisson優化)

ZooKeeper

基于臨時有序節點

,最小序號節點獲得鎖,通過Watcher監聽節點變化 。

強一致性、自動釋放鎖(節點斷開則刪除臨時節點)

性能較低、實現復雜

數據庫

通過唯一約束(如MySQL行鎖、樂觀鎖)或專用鎖表 。

簡單易用

性能差、高并發場景易成瓶頸

3. 關鍵技術細節
  • 鎖續期(看門狗機制):Redisson通過后臺線程定期檢查并延長鎖有效期,避免業務未完成時鎖過期。
  • 可重入性:通過記錄線程標識和重入次數(如Redis的Hash結構)支持同一線程多次加鎖。
  • 容錯設計
    • Redis的RedLock算法需半數以上節點加鎖成功,避免主從切換問題。
    • ZooKeeper通過臨時節點自動清理解決進程宕機導致的死鎖。

四、典型問題與解決方案

  1. 鎖過期但業務未完成
    • 方案:使用守護線程續期(如Redisson的看門狗)或超時回滾+告警。
  1. 鎖誤刪(非持有者釋放鎖)
    • 方案:解鎖時校驗唯一標識(如UUID),并通過Lua腳本保證原子性。

五、總結

分布式鎖通過外部存儲系統實現跨進程資源互斥,需權衡性能、一致性和復雜度。Redis適合高頻低一致性要求的場景,ZooKeeper適用于強一致性但低并發場景,而數據庫鎖僅作為簡單場景的備選。實際選型需結合業務需求和容錯能力(如Redisson整合Redis的方案較優)。

六、具體代碼實現

我們這邊是查詢數據

首先如果緩存命中 就直接返回數據

否則是要去數據庫查詢數據

使用分布式鎖 讓同一時間只能允許一個線程更新緩存

防止碰巧有寫入緩存的線程結束

我們可以進行一個二次檢查 防止那個碰巧情況

因為緩存一旦存在 再次寫入 數據會進行疊加

確認了在分布式鎖內 緩存依舊為空

之后我們就可以去數據庫查詢數據

   @Override// 這邊我們使用redis來輔助mysql查詢 因為數據庫壓力實在是太大了(服務器帶寬太低)public List<GetAllContentResp> getAll() {// 異常處理try {// 1. 構建帶業務標識的復合KeyString cacheKey = "balloonSentences:all" + DATA_VERSION;// 2. 帶熔斷的緩存讀取 如果緩存擊中 直接返回即可 返回的是所有數據List<GetAllContentResp> cachedData = redisService.getList(cacheKey, 0, -1);if (cachedData != null) {if (cachedData.isEmpty()) { // 空值緩存處理return Collections.emptyList();}elasticsearchService.saveProduct(cachedData);  // 寫到elasticsearch里面去return cachedData;} else {// 3. 分布式鎖防穿透 同一時間只允許一個線程更新緩存RLock lock = redissonClient.getLock("lock:" + cacheKey);try {lock.lock(5, TimeUnit.SECONDS);// 二次檢查cachedData = redisService.getList(cacheKey, 0, -1);if (cachedData != null) return cachedData;// 4. 數據庫查詢List<GetAllContentResp> dbData = tSentencesMapper.getAll();// 5. 異步寫緩存和elasticsearch(保證數據庫操作成功)CompletableFuture.runAsync(() -> {// 隨機化TTL防雪崩redisService.setList(cacheKey, dbData, RandomUtil.randomInt(30, 60), TimeUnit.MINUTES);elasticsearchService.saveProduct(dbData);  // 寫到elasticsearch里面去});return dbData;} finally {lock.unlock();}}} catch (Exception e) {e.printStackTrace();}return null;}

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

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

相關文章

案例:使用網絡命名空間模擬多主機并通過網橋訪問外部網絡

案例目標 隔離性&#xff1a;在同一臺物理機上創建兩個獨立的網絡命名空間&#xff08;模擬兩臺主機&#xff09;&#xff0c;確保其網絡配置完全隔離。內部通信&#xff1a;允許兩個命名空間通過虛擬設備直接通信。外部訪問&#xff1a;通過宿主機的網橋和 NAT 規則&#xff…

AF3 Rotation 類解讀

Rotation 類(rigid_utils 模塊)是 AlphaFold3 中用于 3D旋轉 的核心組件,支持兩種旋轉表示: 1?? 旋轉矩陣 (3x3) 2?? 四元數 (quaternion, 4元向量) ?? 設計目標: 允許靈活選擇 旋轉矩陣 或 四元數 封裝了常用的 旋轉操作(組合、逆旋轉、應用到點上等) 像 torch.…

DeepSeek面試——模型架構和主要創新點

本文將介紹DeepSeek的模型架構多頭潛在注意力&#xff08;MLA&#xff09;技術&#xff0c;混合專家&#xff08;MoE&#xff09;架構&#xff0c; 無輔助損失負載均衡技術&#xff0c;多Token 預測&#xff08;MTP&#xff09;策略。 一、模型架構 DeepSeek-R1的基本架構沿用…

【web3】

檢測錢包是否安裝 方法一 // npm install metamask/detect-provider import detectEthereumProvider from metamask/detect-provider// 檢測錢包是否安裝 const isProvider await detectEthereumProvider() if(!isProvider) {proxy.$modal.msgError("請安裝錢包")…

husky的簡介以及如果想要放飛自我的解決方案

husky 是一個 Git Hooks 管理工具&#xff0c;它的主要作用是 在 Git 提交&#xff08;commit&#xff09;、推送&#xff08;push&#xff09;等操作時執行自定義腳本&#xff0c;比如代碼檢查&#xff08;Lint&#xff09;、單元測試&#xff08;Test&#xff09;、格式化代碼…

JVM之類的加載過程

加載 這一階段是將類的字節碼從外部存儲&#xff08;如磁盤&#xff09;加載到JVM的內存中。加載時&#xff0c;JVM會根據類的全限定名&#xff08;包括包名和類名&#xff09;查找相應的字節碼文件&#xff08;.class文件&#xff09;&#xff0c;并將其讀入內存。 鏈接 鏈接…

Java Collection API增強功能系列之六 改進的 ConcurrentHashMap:歸約、搜索、計數與 Set 視圖詳解

Java 8 改進的 ConcurrentHashMap&#xff1a;歸約、搜索、計數與 Set 視圖詳解 Java 8 對 ConcurrentHashMap 進行了重大優化&#xff0c;不僅提升了并發性能&#xff0c;還引入了許多函數式編程方法&#xff0c;使其在處理高并發場景時更加高效和靈活。本文將深入解析 Concu…

AI生成移動端貪吃蛇游戲頁面,手機瀏覽器打開即可玩

貪吃蛇游戲可計分&#xff0c;可穿墻&#xff0c;AI生成適配手機瀏覽器的游戲&#xff0c;代碼如下&#xff1a; <!DOCTYPE html> <html lang"zh-CN"> <head> <meta charset"UTF-8"> <meta name"viewport" …

【動手學深度學習】#4 深度學習計算

主要參考學習資料&#xff1a; 《動手學深度學習》阿斯頓張 等 著 【動手學深度學習 PyTorch版】嗶哩嗶哩跟李牧學AI 概述 為了實現更復雜的網絡&#xff0c;我們需要研究比層更高一級的單元塊&#xff0c;在編程中由類表示。通過自定義層和塊&#xff0c;我們能更靈活地搭建網…

如何在 Windows 上安裝并使用 Postman?

Postman 是一個功能強大的API測試工具&#xff0c;它可以幫助程序員更輕松地測試和調試 API。在本文中&#xff0c;我們將討論如何在 Windows 上安裝和使用 Postman。 Windows 如何安裝和使用 Postman 教程&#xff1f;

php寫入\查詢influxdb數據

namespace app\index\controller;use InfluxDB2\Client; use InfluxDB2\Model\WritePrecision; use InfluxDB2\Point;class Demo {/*** 顯示資源列表** return \think\Response*/public function index(){$token 你的TOKEN;$org zzlichi;$bucket initdb;$client new Client…

26考研——圖_圖的基本概念(6)

408答疑 文章目錄 一、圖的基本概念圖的定義非空性非線性結構 頂點和邊的表示頂點邊 有向圖 & 無向圖有向圖有向圖 G 1 G_1 G1? 的表示 無向圖無向圖 G 2 G_2 G2? 的表示 簡單圖 & 多重圖簡單圖多重圖 頂點的度、入度和出度頂點的度有向圖的度 路徑、路徑長度和回路…

面向對象軟件工程實踐軟件案例

智力運動-數字化思維訓練課程介紹 數字化思維訓練是科技賦能素質教育創新實踐項目&#xff0c;通過數字化信息化手段&#xff0c;深度融合優質原創智力運動教育課程資源&#xff0c;服務幼兒園與小學&#xff0c;提供信息時代校園素質教育教學解決方案。在《面向對象軟件工程》…

Linux學習筆記(應用篇一)

基于I.MX6ULL.MINI開發板 標準I/O庫鏈接目錄刪除文件正則表達式系統標識時間堆內存信號標準信號 進程進程組進程間通信線程互斥鎖線程安全 本文章是入門篇的概念&#xff0c;有點零散&#xff0c;后續需要補充復習 **inode&#xff08;索引節點&#xff09;**是 Linux 和 Unix …

Modbus RTU ---> Modbus TCP透傳技術實現(Modbus透傳、RS485透傳、RTU透傳)分站代碼實現、協議轉換器

文章目錄 Modbus RTU到Modbus TCP透傳技術實現1. 透傳技術概述1.1 透傳基本原理- 協議幀格式轉換- 地址映射與管理- 通信時序適配- 錯誤檢測與處理 2. 透傳網關硬件架構2.1 典型硬件結構- 微控制器/處理器(ARM、STM32等)- RS-485/RS-232收發器- 以太網控制器(如W5500)- 電源管理…

MySQL數據庫中常用的命令

登錄&#xff1a; mysql -u username -h ip地址 -P 端口 -p 密碼 mysql -u username -S /path/mysql.sock -P -p 用戶管理&#xff1a; select user,host from mysql.user;//查看數據庫中所用用戶信息 create user username%;//創建用戶 create user username% identifie…

醫學交互作用分析步驟和目的(R語言)

醫學交互作用分析的目的和用途&#xff08;R語言&#xff09; 醫學交互作用分析一直是醫學數據分析的組成部分&#xff0c;總結最近的一些認識。 目的&#xff1a; 在獨立危險因素鑒定的研究中&#xff0c;&#xff08;獨立危險因素的&#xff09;交互作用可以作為獨立危險因…

Javaweb后端登錄會話技術jwt令牌

jwt生成與校驗 是base4補位的 最后面是簽名&#xff0c;簽名不是base64&#xff0c;是通過簽名算法加密后來的 令牌長度不是固定的&#xff0c;長度取決于原始內容&#xff0c;載荷&#xff0c;大小 頭有&#xff0c;類型&#xff0c;簽名算法 base64可以對任意的二進制數據進…

Mybatis操作數據庫(注解+xml兩個方式)

文章目錄 1.個人回顧2.關于mybatis注解的說明3.字段和屬性不匹配的解決方案3.1第一個方案3.2第二個方案3.3第三個方案 4.xml路徑配置5.xml里面的字段映射 1.個人回顧 剛剛翻看了一下自己的這個之前寫的博客&#xff0c;上一次和這個javaee相關的博客還是去年寫的&#xff0c;也…

SysVinit和Systemd的系統運行級別

Linux運行級別 SysVinit系統(init守護進程)Linux系統運行級別SysVinit系統(init守護進程)查看Linux運行級別SysVinit系統(init守護進程)修改運行級別&#xff1a; Systemd守護進程Linux系統運行級別systemd查看運行級別Systemd查看系統當前運行級別 systemd修改運行級別multi-u…