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

redis分布式鎖詳解Redisson(RedissonClient)

 更新時間:2025年11月19日 09:10:28   作者:碼上走人  
Redisson提供了多種鎖和實用方法,實現(xiàn)了對數(shù)據(jù)的增刪改查等操作,RedissonClient接口的實現(xiàn)類中,重點介紹了重入鎖、公平鎖和聯(lián)鎖的實現(xiàn)方式,在實際應用中,設置定時過期的分布式鎖需要考慮服務宕機或重啟的問題,可以通過記錄鎖的Set來解決

RedissonClient中提供了好多種鎖,還有其它很多實用的方法。

Redisson是Redis官方推薦的Java版的Redis客戶端。實現(xiàn)了對數(shù)據(jù)的增刪改查等操作。

Redisson實現(xiàn)了RedissonClient的接口。這里只介紹其中的鎖。

依賴

<dependency>
      <groupId>org.redisson</groupId>
      <artifactId>redisson</artifactId>
      <version>3.10.7</version>
</dependency>

重入鎖 RedissonLock

重入鎖可以通過Redisson的getLock方法獲取

@Override
public RLock getLock(String name) {
    return new RedissonLock(connectionManager.getCommandExecutor(), name);
}
/**
     * 獲取鎖-同一個線程可重入
     * @param lockKey  鎖的名稱
     * @param waitTime 獲取鎖的等待時間
     * @param leaseTime 鎖的持續(xù)時間
     * @param unit  時間的單位
     * @return 獲取鎖的結果
     */
    public Boolean tryLock(String lockKey, long waitTime, long leaseTime, TimeUnit unit) {
        RLock lock = redissonClient.getLock(lockKey);
        try {
            // 1. 最常見的使用方法
            //lock.lock();
            // 2. 支持過期解鎖功能,10秒鐘以后自動解鎖, 無需調用unlock方法手動解鎖
            //lock.lock(10, TimeUnit.SECONDS);
            boolean locked = lock.tryLock(waitTime, leaseTime, unit);
            if (locked) lockKeys.add(lockKey);
            return locked;
        } catch (InterruptedException e) {
            System.out.println(String.format("嘗試獲取鎖%s失敗", lockKey));
            e.printStackTrace();
        }
        return Boolean.FALSE;
    }

    /**
     * 解鎖 - 重入的方式,所以同一個線程加了幾次鎖就要釋放幾次鎖
     * @param lockKey 鎖的值
     */
    public boolean unLock(String lockKey) {
        try {
            RLock lock = redissonClient.getLock(lockKey);
            if (null != lock && lock.isHeldByCurrentThread()) { //判斷鎖是否存在,和是否當前線程加的鎖。
                lock.unlock();
                return lockKeys.remove(lockKey);
            }
        } catch (Exception e) {
            System.out.println(String.format("解鎖鎖%s失敗", lockKey));
            e.printStackTrace();
        }
        return false;
    }

重入鎖的異步執(zhí)行方式

/**
     * 異步獲取鎖-同一個線程可重入
     * @param lockKey  鎖的名稱
     * @param waitTime 獲取鎖的等待時間
     * @param leaseTime 鎖的持續(xù)時間
     * @param unit  時間的單位
     * @return 獲取鎖的結果
     */
    public Boolean tryLockAsync(String lockKey, long waitTime, long leaseTime, TimeUnit unit) {
        RLock lock = redissonClient.getLock(lockKey);
        try {
            // 1. 最常見的使用方法
            //lock.lockAsync();
            // 2. 支持過期解鎖功能,10秒鐘以后自動解鎖, 無需調用unlock方法手動解鎖
            //lock.lockAsync(10, TimeUnit.SECONDS);
            RFuture<Boolean> locked = lock.tryLockAsync(waitTime, leaseTime, unit);
            if (locked.get()) lockKeys.add(lockKey);
            return locked.get();
        } catch (InterruptedException | ExecutionException e) {
            System.out.println(String.format("嘗試獲取鎖%s失敗", lockKey));
            e.printStackTrace();
        }
        return Boolean.FALSE;
    }

    /**
     * 解鎖 - 重入的方式,所以同一個線程加了幾次鎖就要釋放幾次鎖
     * @param lockKey 鎖的值
     */
    public boolean unAsyncLock(String lockKey) {
        try {
            RLock lock = redissonClient.getLock(lockKey);
            if (null != lock && lock.isHeldByCurrentThread()) { //判斷鎖是否存在,和是否當前線程加的鎖。
                RFuture<Void> future = lock.unlockAsync();
                if(future.await(5 * 1000) && future.isSuccess()) {
                    return lockKeys.remove(lockKey);
                }
            }
        } catch (Exception e) {
            System.out.println(String.format("解鎖%s失敗", lockKey));
            e.printStackTrace();
        }
        return false;
    }

公平鎖

改公平鎖是可重入的,在提供了自動過期解鎖功能的同時,保證了當多個Redisson客戶端線程同時請求加鎖時,優(yōu)先分配給先發(fā)出請求的線程。同時也提供了異步的方式。

實現(xiàn)方式參照上一個鎖的實現(xiàn)。

@Override
public RLock getFairLock(String name) {
    return new RedissonFairLock(connectionManager.getCommandExecutor(), name);
}
/**
     * 公平鎖
     *
     * @param lockKey 鎖的名稱
     * @param waitTime 獲取鎖的等待時間
     * @param leaseTime 鎖的持續(xù)時間
     * @param unit 時間的單位
     *
     * @return 獲取鎖的結果
     */
    public Boolean tryFairLock(String lockKey, long waitTime, long leaseTime, TimeUnit unit) {
        RLock lock = redissonClient.getFairLock(lockKey);
        try {
            // 1. 最常見的使用方法
            //lock.tryLock();
            // 2. 支持過期解鎖功能,10秒鐘以后自動解鎖, 無需調用unlock方法手動解鎖
            //lock.tryLock(10, TimeUnit.SECONDS);
            boolean locked = lock.tryLock(waitTime, leaseTime, unit);
            if (locked)
                lockKeys.add(lockKey);
            return locked;
            /* 異步實現(xiàn)方式
            lock.lockAsync();
            lock.lockAsync(10, TimeUnit.SECONDS);
            RFuture<Boolean> locked = lock.tryLockAsync(waitTime, leaseTime, unit);
            if (locked.get()) lockKeys.add(lockKey);
            return locked.get();*/
        } catch (InterruptedException e) {
            System.out.println(String.format("嘗試獲取鎖%s失敗", lockKey));
            e.printStackTrace();
        }
        return Boolean.FALSE;
    }

    /**
     * 解鎖 - 重入的方式,所以同一個線程加了幾次鎖就要釋放幾次鎖
     *
     * @param lockKey 鎖的值
     */
    public boolean unFairLock(String lockKey) {
        try {
            RLock lock = redissonClient.getFairLock(lockKey);
            if (null != lock && lock.isHeldByCurrentThread()) { //判斷鎖是否存在,和是否當前線程加的鎖。
                lock.unlock();
                return lockKeys.remove(lockKey);

                //異步方式刪除鎖
                /*RFuture<Void> future = lock.unlockAsync();
                if (future.await(5 * 1000) && future.isSuccess()) {
                    return lockKeys.remove(lockKey);
                }*/
            }
        } catch (Exception e) {
            System.out.println(String.format("解鎖%s失敗", lockKey));
            e.printStackTrace();
        }
        return false;
    }

聯(lián)鎖(MultiLock)

Redisson的RedissonMultiLock對象可以將多個RLock對象關聯(lián)為一個聯(lián)鎖,每個RLock對象實例可以來自于不同的Redisson實例。

需要注意的是,在鎖的釋放時,可以單獨釋放Redisson添加的鎖,其他鎖不會釋放依舊存在。

/**
     * 連鎖-只有所有的RedissonClient都鎖成功才算成功
     *
     * @param waitTime 獲取鎖的等待時間
     * @param leaseTime 鎖的持續(xù)時間
     * @param unit 時間的單位
     *
     * @return 獲取鎖的結果
     */
    public Boolean tryMultiLock(RedissonClient redisson1,RedissonClient redisson2, long waitTime, long leaseTime, TimeUnit unit){
        RLock lock1 = redisson1.getLock("zhong:test:lock1");
        RLock lock2 = redisson2.getLock("zhong:test:lock2");
        RLock lock = redissonClient.getMultiLock(lock1, lock2);
        try {
            // 同時加鎖:lock1 lock2 lock3, 所有的鎖都上鎖成功才算成功。
            lock.lock();
            // 嘗試加鎖,最多等待100秒,上鎖以后10秒自動解鎖
            boolean res = lock.tryLock(waitTime, unit);
            return res;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
        return false;
    }
    /**
     * 連鎖 - 需要遵循誰加的鎖設計釋放鎖,可以單獨釋放自己加的鎖
     *
     */
    public boolean unMultiLock(RedissonClient client ,RedissonClient client1) {
        try {
            List<RLock> locks = new ArrayList<>();
            locks.add(client.getLock("zhong:test:lock1"));
            locks.add(client1.getLock("zhong:test:lock2"));
            RedissonMultiLock lock = new RedissonMultiLock(locks.toArray(new RLock[0]));
            lock.unlock();

            //異步方式刪除鎖
            /*RFuture<Void> future = lock.unlockAsync();
            if (future.await(5 * 1000) && future.isSuccess()) {
                return lockKeys.remove(lockKey);
            }*/
        } catch (Exception e) {
            System.out.println(String.format("解鎖失敗"));
            e.printStackTrace();
            return false;
        }
        return true;
    }

 RedissonClient還提供了紅鎖,讀寫鎖等。

在實際應用中我們最常用的分布式鎖一般都是設置定時過期的。

這樣的鎖在實際應用中存在一個問題就是服務宕機或重啟這個鎖在redis上是一直存在的。一旦重啟就可能會導致所有線程無法獲取到鎖。

解決辦法就是在加鎖的時候將鎖記錄到Set里面。釋放鎖的時候將記錄Set中的鎖刪除,在服務停止之前就就根據(jù)set記錄里面的鎖先將歐鎖釋放。

這樣就能保證重啟后能獲取到鎖。實現(xiàn)方式參考DisposableBean的實現(xiàn)方式。

總結

以上為個人經驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關文章

  • Java設計模式之命令模式

    Java設計模式之命令模式

    這篇文章介紹了Java設計模式之命令模式,文中通過示例代碼介紹的非常詳細。對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-10-10
  • Spring Cloud Consul的服務注冊與發(fā)現(xiàn)

    Spring Cloud Consul的服務注冊與發(fā)現(xiàn)

    這篇文章主要介紹了Spring Cloud Consul服務注冊與發(fā)現(xiàn)的實現(xiàn)方法,幫助大家更好的理解和學習使用spring框架,感興趣的朋友可以了解下
    2021-02-02
  • 在maven工程里運行java main方法

    在maven工程里運行java main方法

    這篇文章主要介紹了在maven工程里運行java main方法,需要的朋友可以參考下
    2014-04-04
  • Java中AuthorizationFilter過濾器的功能

    Java中AuthorizationFilter過濾器的功能

    本文主要介紹了Java中AuthorizationFilter過濾器的功能,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2026-02-02
  • Java編程獲取文件列表及子文件目錄的方法(非遞歸)

    Java編程獲取文件列表及子文件目錄的方法(非遞歸)

    這篇文章主要介紹了Java編程獲取文件列表及子文件目錄的方法(非遞歸),具有一定參考價值,需要的朋友可以了解下。
    2017-10-10
  • Java commons-httpclient如果實現(xiàn)get及post請求

    Java commons-httpclient如果實現(xiàn)get及post請求

    這篇文章主要介紹了Java commons-httpclient如果實現(xiàn)get及post請求,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-09-09
  • Java中List和Map的多層嵌套與拆分技巧

    Java中List和Map的多層嵌套與拆分技巧

    在Java開發(fā)中,處理復雜的嵌套數(shù)據(jù)結構是一項基本但至關重要的技能,本文給大家介紹Java中List和Map的多層嵌套與拆分問題,感興趣的朋友跟隨小編一起看看吧
    2026-02-02
  • IDEA2022.2的簡介、下載與安裝、配置教程

    IDEA2022.2的簡介、下載與安裝、配置教程

    IDEA是JetBrains公司推出一個集成開發(fā)工具,是Java開發(fā)工具中的翹楚,基于這個開發(fā)工具可以快速開發(fā)我們的Java相關項目,本文重點給大家介紹IDEA2022.2的簡介、下載與安裝、初步配置,感興趣的朋友一起看看吧
    2022-11-11
  • IDEA 開發(fā)多項目依賴的方法(圖文)

    IDEA 開發(fā)多項目依賴的方法(圖文)

    這篇文章主要介紹了IDEA 開發(fā)多項目依賴的方法(圖文),本文講一下關于使用IntelliJ IDEA基于Maven創(chuàng)建多模塊項目的實際開發(fā),非常具有實用價值,需要的朋友可以參考下
    2018-10-10
  • springboot2.3之后hibernate-validator依賴缺失【踩坑】

    springboot2.3之后hibernate-validator依賴缺失【踩坑】

    這篇文章主要介紹了springboot2.3之后hibernate-validator依賴缺失【踩坑】,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-11-11

最新評論

秭归县| 广昌县| 广东省| 虎林市| 莱西市| 报价| 余姚市| 湖州市| 汉沽区| 察雅县| 恩平市| 浑源县| 海阳市| 井陉县| 揭东县| 措勤县| 闸北区| 新野县| 临沧市| 绥滨县| 全南县| 浠水县| 宜兰县| 宁明县| 铜梁县| 广汉市| 南江县| 柘荣县| 平乡县| 九江市| 靖安县| 霍州市| 容城县| 绥德县| 阳朔县| 苍南县| 句容市| 都兰县| 原阳县| 德阳市| 通化县|