欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java中的分布式鎖與同步鎖使用詳解

 更新時間:2023年07月19日 15:05:19   作者:IT小輝同學  
這篇文章主要介紹了Java中的分布式鎖與同步鎖使用詳解,在分布式系統(tǒng)中,由于存在多個節(jié)點并行執(zhí)行任務,可能會出現(xiàn)競爭條件和數(shù)據(jù)不一致的問題,分布式鎖通過約束同一時刻只有一個節(jié)點能夠獲得鎖的方式,確保了對共享資源的獨占訪問,需要的朋友可以參考下

什么是分布式鎖

分布式鎖是一種在分布式系統(tǒng)中用于協(xié)調(diào)多個節(jié)點訪問共享資源的機制。在分布式系統(tǒng)中,由于存在多個節(jié)點并行執(zhí)行任務,可能會出現(xiàn)競爭條件和數(shù)據(jù)不一致的問題。分布式鎖通過約束同一時刻只有一個節(jié)點能夠獲得鎖的方式,確保了對共享資源的獨占訪問,從而解決了這些問題。

在這里插入圖片描述

分布式鎖的實現(xiàn)通常需要滿足以下特性:

  1. 互斥性:同一時刻只有一個節(jié)點能夠持有鎖,并且其他節(jié)點無法獲取該鎖。
  2. 可重入性:允許同一節(jié)點多次獲取同一個鎖,而不會發(fā)生死鎖。
  3. 容錯性:在鎖持有者節(jié)點故障或網(wǎng)絡異常情況下,能夠及時釋放鎖。
  4. 超時處理:支持設置獲取鎖的最大等待時間,避免由于死鎖或長時間阻塞導致系統(tǒng)性能下降。
  5. 高可用性:具備高可用性能,即使部分節(jié)點故障也能正常提供服務。

實現(xiàn)分布式鎖的方法有多種,常見的包括:

  1. 基于數(shù)據(jù)庫的分布式鎖:利用數(shù)據(jù)庫的事務和唯一索引等特性,使用數(shù)據(jù)庫表記錄鎖的狀態(tài)。通過獲取和釋放特定的行鎖來實現(xiàn)互斥訪問。
  2. 基于緩存的分布式鎖:利用分布式緩存(如Redis)的原子性操作和過期時間等特點,通過設置一個全局唯一的鍵值對表示鎖的狀態(tài)。只有成功獲取到鎖的節(jié)點才能在緩存中設置這個鍵值對,其他節(jié)點則無法設置并獲取到鎖。

什么是同步鎖

同步鎖是一種并發(fā)控制機制,用于在多線程環(huán)境下保護共享資源的訪問。它可以防止多個線程同時訪問臨界區(qū)代碼,從而避免并發(fā)訪問導致的數(shù)據(jù)不一致或沖突。

同步鎖的原理是通過獲取鎖來獲得對臨界區(qū)代碼的獨占訪問權。在Java中,常用的同步鎖機制包括內(nèi)置鎖(也稱為監(jiān)視器鎖)和顯式鎖。

  • 內(nèi)置鎖(Intrinsic Lock):也稱為對象監(jiān)視器鎖或synchronized鎖。當一個方法或代碼塊被synchronized修飾時,該對象上就存在一個內(nèi)置鎖。只有獲得了該鎖的線程才能執(zhí)行被修飾的方法或代碼塊,其他線程必須等待鎖的釋放。

示例代碼:

public class Example {
    private Object lock = new Object();
    public void synchronizedMethod() {
        synchronized (lock) {
            // 臨界區(qū)代碼
        }
    }
}
  • 顯式鎖(Explicit Lock):使用java.util.concurrent.locks包中的Lock接口及其實現(xiàn)類,如ReentrantLock。相比內(nèi)置鎖,顯式鎖提供了更靈活的鎖定機制,如可重入性、公平性和條件變量等特性,使得多線程代碼的控制更加精確。

示例代碼:

public class Example {
    private Lock lock = new ReentrantLock();
    public void lockedMethod() {
        lock.lock();
        try {
            // 臨界區(qū)代碼
        } finally {
            lock.unlock();
        }
    }
}

同步鎖的使用可以有效避免多個線程對共享資源的不安全訪問,保證數(shù)據(jù)一致性和并發(fā)執(zhí)行的正確性。但過度使用同步鎖可能導致線程競爭和性能下降,因此在設計多線程應用程序時需要合理地使用同步鎖機制。

兩種鎖的使用場景

分布式鎖和同步鎖是在不同環(huán)境下用于實現(xiàn)并發(fā)控制的兩種機制。

  • 分布式鎖的使用場景: 分布式鎖通常用于分布式系統(tǒng)中,用于協(xié)調(diào)多個節(jié)點對共享資源的訪問。

一個常見的場景是在分布式環(huán)境下實現(xiàn)對某個唯一資源的排他性訪問,例如分布式任務調(diào)度、分布式緩存更新等。

示例代碼(基于Redis實現(xiàn)分布式鎖):

import redis.clients.jedis.Jedis;
public class DistributedLock {
    private Jedis jedis;
    private String lockKey;
    public boolean acquireLock() {
        long result = jedis.setnx(lockKey, "locked");
        return result == 1;
    }
    public void releaseLock() {
        jedis.del(lockKey);
    }
}

在上述代碼中,通過調(diào)用 setnx() 方法嘗試獲取鎖,如果返回值為1,則表示成功獲取到分布式鎖。釋放鎖的操作則是調(diào)用 del() 方法刪除鎖的鍵。

  • 同步鎖的使用場景: 同步鎖主要用于多線程編程中,控制多個線程對共享資源的并發(fā)訪問。

一個經(jīng)典的場景是在多線程環(huán)境下保護對某個臨界區(qū)代碼的獨占訪問,避免數(shù)據(jù)競爭和沖突。

示例代碼(基于Java內(nèi)置鎖實現(xiàn)同步鎖):

public class SynchronizedCounter {
    private int count;
    public synchronized void increment() {
        count++;
    }
    public synchronized void decrement() {
        count--;
    }
}

在上述代碼中,通過 synchronized 關鍵字修飾方法,使得多線程在執(zhí)行這些方法時會自動獲取對象的內(nèi)置鎖。

這樣可以確保同一時間只能有一個線程執(zhí)行 increment()decrement() 方法,避免并發(fā)訪問

分布式鎖實現(xiàn)

分布式鎖是在分布式系統(tǒng)中用于實現(xiàn)資源的互斥訪問的一種機制。下面介紹兩種常見的分布式鎖實現(xiàn)方法:

  • 基于數(shù)據(jù)庫的分布式鎖: 使用數(shù)據(jù)庫作為分布式鎖的持久化存儲,通過在表中創(chuàng)建唯一索引或使用悲觀鎖來確保只有一個節(jié)點能夠成功獲取鎖。
// 獲取分布式鎖
public boolean acquireLock(String lockName) {
    try (Connection connection = dataSource.getConnection()) {
        String sql = "INSERT INTO distributed_lock (lock_name) VALUES (?)";
        PreparedStatement statement = connection.prepareStatement(sql);
        statement.setString(1, lockName);
        int affectedRows = statement.executeUpdate();
        return affectedRows > 0;
    } catch (SQLException e) {
        // 處理異常
    }
    return false;
}
// 釋放分布式鎖
public void releaseLock(String lockName) {
    try (Connection connection = dataSource.getConnection()) {
        String sql = "DELETE FROM distributed_lock WHERE lock_name = ?";
        PreparedStatement statement = connection.prepareStatement(sql);
        statement.setString(1, lockName);
        statement.executeUpdate();
    } catch (SQLException e) {
        // 處理異常
    }
}

在上述示例中,使用數(shù)據(jù)庫表 distributed_lock 存儲分布式鎖的狀態(tài)。

通過執(zhí)行相應的SQL語句來獲取鎖和釋放鎖,確保只有一個節(jié)點能夠插入對應的鎖名稱到表中。其他節(jié)點嘗試插入同樣的鎖名稱會因為唯一索引或悲觀鎖失敗,從而實現(xiàn)了互斥訪問。

  • 基于Redis的分布式鎖: 使用Redis作為分布式鎖的存儲中心,利用Redis的原子操作特性和過期時間來實現(xiàn)分布式鎖的獲取和釋放。
public boolean acquireLock(String lockKey, String requestId, int expireTime) {
    try (Jedis jedis = jedisPool.getResource()) {
        String result = jedis.set(lockKey, requestId, "NX", "PX", expireTime);
        return "OK".equalsIgnoreCase(result);
    } catch (Exception e) {
        // 處理異常
    }
    return false;
}
public void releaseLock(String lockKey, String requestId) {
    try (Jedis jedis = jedisPool.getResource()) {
        String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
        jedis.eval(script, Collections.singletonList(lockKey), Collections.singletonList(requestId));
    } catch (Exception e) {
        // 處理異常
    }
}

在上述示例中,使用Redis的 set 命令以原子方式將鎖信息存儲到Redis中,并設置過期時間。

通過獲取鎖時傳遞一個唯一的請求標識符 requestId,并在釋放鎖時校驗該標識符,確保只有持有鎖的節(jié)點能夠釋放它。

這兩種分布式鎖的實現(xiàn)方法各有優(yōu)劣,選擇合適的方式取決于具體業(yè)務場景和系統(tǒng)需求。分布式鎖的設計和實現(xiàn)需要考慮到分布式環(huán)境下的并發(fā)性、可靠性和性能等方面的問題,確保在多個節(jié)點之間實現(xiàn)正確的資源互斥訪問。

到此這篇關于Java中的分布式鎖與同步鎖使用詳解的文章就介紹到這了,更多相關分布式鎖與同步鎖內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • DDD框架落地實戰(zhàn)

    DDD框架落地實戰(zhàn)

    這篇文章主要為大家介紹了DDD框架落地實戰(zhàn)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-08-08
  • SpringBoot整合WebService服務的實現(xiàn)代碼

    SpringBoot整合WebService服務的實現(xiàn)代碼

    WebService是一個SOA(面向服務的編程)的架構(gòu),它是不依賴于語言,不依賴于平臺,可以實現(xiàn)不同的語言間的相互調(diào)用,通過Internet進行基于Http協(xié)議的網(wǎng)絡應用間的交互,這篇文章主要介紹了SpringBoot整合WebService服務的實例代碼,需要的朋友可以參考下
    2022-02-02
  • MybatisPlus特殊查詢的實現(xiàn)介紹

    MybatisPlus特殊查詢的實現(xiàn)介紹

    這篇文章主要介紹了MybatisPlus查詢投影、聚合查詢、分組查詢、等值查詢、范圍查詢、模糊查詢、排序查詢,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習吧
    2022-10-10
  • 類添加注解@RequestMapping報錯HTTP Status 404的解決

    類添加注解@RequestMapping報錯HTTP Status 404的解決

    這篇文章主要介紹了類添加注解@RequestMapping報錯HTTP Status 404的解決,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • Springboot啟動停止命令的.sh腳本編寫方式

    Springboot啟動停止命令的.sh腳本編寫方式

    這篇文章主要介紹了Springboot啟動停止命令的.sh腳本編寫方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-05-05
  • CountDownLatch和Atomic原子操作類源碼解析

    CountDownLatch和Atomic原子操作類源碼解析

    這篇文章主要為大家介紹了CountDownLatch和Atomic原子操作類的源碼解析以及理解應用,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步
    2022-03-03
  • 使用Java自制一個一個Nacos

    使用Java自制一個一個Nacos

    Nacos是?Dynamic?Naming?and?Configuration?Service的首字母簡稱,一個更易于構(gòu)建云原生應用的動態(tài)服務發(fā)現(xiàn)、配置管理和服務管理平臺,本文將嘗試用Java實現(xiàn)一個Nacos,感興趣的可以了解下
    2024-01-01
  • Spring框架JdbcTemplate數(shù)據(jù)庫事務管理完全注解方式

    Spring框架JdbcTemplate數(shù)據(jù)庫事務管理完全注解方式

    這篇文章主要介紹了Spring框架JdbcTemplate數(shù)據(jù)庫事務管理及完全注解方式,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-05-05
  • webuploader 實現(xiàn)圖片批量上傳功能附實例代碼

    webuploader 實現(xiàn)圖片批量上傳功能附實例代碼

    這篇文章主要介紹了webuploader 實現(xiàn)圖片批量上傳功能,非常不錯,具有參考借鑒價值,需要的朋友可以參考下
    2017-11-11
  • Java虛擬機執(zhí)行引擎知識總結(jié)

    Java虛擬機執(zhí)行引擎知識總結(jié)

    這篇文章主要介紹了有關Java虛擬機執(zhí)行引擎的知識,文中實例簡單易懂,方便大家更好的學習,有興趣的朋友可以了解下
    2020-06-06

最新評論