3. 分散式鎖
阿新 • • 發佈:2021-09-13
Java中的鎖 可以簡單的理解為多執行緒情況下訪問臨界資源的一種執行緒同步機制
為什麼要使用分散式鎖
我們在開發應用的時候,如果需要對某一個共享變數進行多執行緒同步訪問的時候,可以使用我們學到的Java多執行緒的18般武藝進行處理,並且可以完美的執行,毫無Bug! 注意這是單機應用,也就是所有的請求都會分配到當前伺服器的JVM內部,然後對映為作業系統的執行緒進行處理!而這個共享變數只是在這個JVM內部的一塊記憶體空間! 後來業務發展,需要做叢集,一個應用需要部署到幾臺機器上然後做負載均衡, 大致如下圖: 上圖可以看到,變數A存在JVM1、JVM2、JVM3三個JVM記憶體中(這個變數A主要體現是在一個類中的一個成員變數,是一個有狀態的物件,例如:UserController控制器中的一個整形型別的成員變數),如果不加任何控制的話,變數A同時都會在JVM分配一塊記憶體,三個請求發過來同時對這個變數操作,顯然結果是不對的!即使不是同時發過來,三個請求分別操作三個不同JVM記憶體區域的資料,變數A之間不存在共享,也不具有可見性,處理的結果也是不對的!分散式鎖應該具備哪些條件
1、在分散式系統環境下,一個方法在同一時間只能被一個機器的一個執行緒執行;分散式鎖的三種實現方式
在很多場景中,我們為了保證資料的最終一致性,需要很多的技術方案來支援,比如分散式事務、分散式鎖等。有的時候,我們需要保證一個方法在同一時間內只能被同一個執行緒執行。 基於資料庫實現分散式鎖; 基於快取(Redis等)實現分散式鎖; 基於Zookeeper實現分散式鎖;四、基於資料庫的實現方式
基於資料庫的實現方式的核心思想是:在資料庫中建立一個表,表中包含方法名等欄位,並在方法名欄位上建立唯一索引五、基於Redis的實現方式
1、選用Redis實現分散式鎖原因: (1)Redis有很高的效能; (2)Redis命令對此支援較好,實現起來比較方便 2、使用命令介紹: (1)SETNX SETNX key val:當且僅當key不存在時,set一個key為val的字串,返回1;若key存在,則什麼都不做,返回0。 1 (2)expire expire key timeout:為key設定一個超時時間,單位為second,超過這個時間鎖會自動釋放,避免死鎖。 1 (3)delete delete key:刪除key 1 在使用Redis實現分散式鎖的時候,主要就會使用到這三個命令。3、實現思想: (1)獲取鎖的時候,使用setnx加鎖,並使用expire命令為鎖新增一個超時時間,超過該時間則自動釋放鎖,鎖的value值為一個隨機生成的UUID,通過此在釋放鎖的時候進行判斷。 (2)獲取鎖的時候還設定一個獲取的超時時間,若超過這個時間則放棄獲取鎖。 (3)釋放鎖的時候,通過UUID判斷是不是該鎖,若是該鎖,則執行delete進行鎖釋放。 4、 分散式鎖的簡單實現程式碼: https://xuliugen.blog.csdn.net/article/details/79036337?utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7Edefault-10.control&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7Edefault-10.control
5、測試剛才實現的分散式鎖 使用50個執行緒模擬秒殺一個商品