最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

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

什么是分布式鎖

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

在這里插入圖片描述

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

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

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

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

什么是同步鎖

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

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

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

示例代碼:

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

示例代碼:

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

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

兩種鎖的使用場(chǎng)景

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

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

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

示例代碼(基于Redis實(shí)現(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);
    }
}

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

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

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

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

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

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

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

分布式鎖實(shí)現(xiàn)

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

  • 基于數(shù)據(jù)庫(kù)的分布式鎖: 使用數(shù)據(jù)庫(kù)作為分布式鎖的持久化存儲(chǔ),通過(guò)在表中創(chuàng)建唯一索引或使用悲觀鎖來(lái)確保只有一個(gè)節(jié)點(diǎn)能夠成功獲取鎖。
// 獲取分布式鎖
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ù)庫(kù)表 distributed_lock 存儲(chǔ)分布式鎖的狀態(tài)。

通過(guò)執(zhí)行相應(yīng)的SQL語(yǔ)句來(lái)獲取鎖和釋放鎖,確保只有一個(gè)節(jié)點(diǎn)能夠插入對(duì)應(yīng)的鎖名稱到表中。其他節(jié)點(diǎn)嘗試插入同樣的鎖名稱會(huì)因?yàn)槲ㄒ凰饕虮^鎖失敗,從而實(shí)現(xiàn)了互斥訪問(wèn)。

  • 基于Redis的分布式鎖: 使用Redis作為分布式鎖的存儲(chǔ)中心,利用Redis的原子操作特性和過(guò)期時(shí)間來(lái)實(shí)現(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 命令以原子方式將鎖信息存儲(chǔ)到Redis中,并設(shè)置過(guò)期時(shí)間。

通過(guò)獲取鎖時(shí)傳遞一個(gè)唯一的請(qǐng)求標(biāo)識(shí)符 requestId,并在釋放鎖時(shí)校驗(yàn)該標(biāo)識(shí)符,確保只有持有鎖的節(jié)點(diǎn)能夠釋放它。

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

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

相關(guān)文章

  • ElasticSearch自定義注解增刪改方式

    ElasticSearch自定義注解增刪改方式

    這篇文章主要介紹了ElasticSearch自定義注解增刪改方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2025-04-04
  • Java中Map轉(zhuǎn)List及List轉(zhuǎn)Map的方法(簡(jiǎn)單好用!)

    Java中Map轉(zhuǎn)List及List轉(zhuǎn)Map的方法(簡(jiǎn)單好用!)

    這篇文章主要給大家介紹了關(guān)于Java中Map轉(zhuǎn)List及List轉(zhuǎn)Map的相關(guān)資料,可以使用Java 8的Stream API將Java Map轉(zhuǎn)換為L(zhǎng)ist,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-07-07
  • Java實(shí)現(xiàn)List去重的方法詳解

    Java實(shí)現(xiàn)List去重的方法詳解

    本文用示例介紹Java的List(ArrayList、LinkedList等)的去重的方法。List去重的常用方法一般是:JDK8的stream的distinct、轉(zhuǎn)為HashSet、轉(zhuǎn)為TreeSet等,感興趣的可以了解一下
    2022-05-05
  • java正則替換sql中的參數(shù)實(shí)例代碼

    java正則替換sql中的參數(shù)實(shí)例代碼

    這篇文章主要給大家介紹了關(guān)于java正則替換sql中參數(shù)的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2022-10-10
  • springboot+thymeleaf國(guó)際化之LocaleResolver接口的示例

    springboot+thymeleaf國(guó)際化之LocaleResolver接口的示例

    本篇文章主要介紹了springboot+thymeleaf國(guó)際化之LocaleResolver的示例 ,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-11-11
  • 在Map中實(shí)現(xiàn)key唯一不重復(fù)操作

    在Map中實(shí)現(xiàn)key唯一不重復(fù)操作

    這篇文章主要介紹了在Map中實(shí)現(xiàn)key唯一不重復(fù)操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • java的list集合排序自定義元素方式

    java的list集合排序自定義元素方式

    在Java中,對(duì)包含自定義元素的List集合進(jìn)行排序可以使用Collections.sort()方法,并結(jié)合自定義的比較器實(shí)現(xiàn),以Student類為例,通過(guò)實(shí)現(xiàn)Comparator接口來(lái)按學(xué)生年齡升序排序
    2024-12-12
  • Java中的ThreadLocal與ThreadLocalMap詳解

    Java中的ThreadLocal與ThreadLocalMap詳解

    這篇文章主要介紹了Java中的ThreadLocal與ThreadLocalMap詳解,ThreadLocal 是一個(gè)線程局部變量,其實(shí)的功用非常簡(jiǎn)單,就是為每一個(gè)使用該變量的線程都提供一個(gè)變量值的副本,是Java中一種較為特殊的線程綁定機(jī)制,需要的朋友可以參考下
    2023-09-09
  • Java?Selenium實(shí)現(xiàn)修改打開(kāi)頁(yè)面窗口大小

    Java?Selenium實(shí)現(xiàn)修改打開(kāi)頁(yè)面窗口大小

    Selenium是一個(gè)強(qiáng)大的自動(dòng)化測(cè)試工具,支持多種編程語(yǔ)言和瀏覽器,本文將詳細(xì)介紹如何使用Java?Selenium來(lái)修改打開(kāi)頁(yè)面窗口的大小,需要的可以參考下
    2025-01-01
  • Java中Integer.equals的用法與特殊情況

    Java中Integer.equals的用法與特殊情況

    Java中Integer.equals比較數(shù)值而非對(duì)象地址,自動(dòng)裝箱處理int參數(shù),-128~127范圍內(nèi)使用==安全,超出范圍或null需用Objects.equals,compareTo用于大小比較,equals僅判斷相等性,注意類型不匹配會(huì)導(dǎo)致false
    2025-07-07

最新評(píng)論

陆川县| 和平区| 纳雍县| 增城市| 甘谷县| 荆州市| 太保市| 阿荣旗| 永济市| 景洪市| 东乌| 岑巩县| 仁布县| 南平市| 林芝县| 潮州市| 通海县| 义马市| 信宜市| 吴忠市| 广灵县| 太原市| 永安市| 彭山县| 榆中县| 泊头市| 宜兰市| 黎城县| 特克斯县| 周宁县| 淮南市| 无棣县| 焦作市| 莱西市| 泰和县| 田林县| 和林格尔县| 南安市| 津南区| 太湖县| 霍林郭勒市|