當前位置:首頁 > IT技術 > 其他 > 正文

Redisson
2022-08-30 00:02:23

https://github.com/redisson/redisson/wiki/2.-%E9%85%8D%E7%BD%AE%E6%96%B9%E6%B3%95#26-%E5%8D%95redis%E8%8A%82%E7%82%B9%E6%A8%A1%E5%BC%8F
<dependency>
    <groupId>org.redisson</groupId>
    <artifactId>redisson</artifactId>
    <version>3.14.1</version>
</dependency>

以配置類的形式設置

?

?

@Configuration
public class MyRedisConfig {
    
    @Bean
    public RedissonClient redissonClient(){
        Config config = new Config();
        //配置鏈接的信息
        config.useSingleServer().setAddress("redis://192.168.1.137:6379");
        RedissonClient redissonClient = Redisson.create();
        return redissonClient;
    }
}

ls -l /proc/7579/cwd
接下來我們看 分布式鎖 的可重入鎖(Reentrant Lock) 同一個對象的同一把鎖 是可以進入

?

 @ResponseBody
    @GetMapping("/hello")
    public String hello(){
        RLock myLock = redissonClient.getLock("myLock");
        // 加鎖
       // myLock.lock();
        //通過效果演示我們可以發(fā)現(xiàn)  指定了過期時間后  自動續(xù)期就不會生效了  這時我們就需要注意設置過期時間一定要滿足我們得業(yè)務場景     默認情況下,看門狗的檢查鎖的超時時間是30秒鐘,也可以通過yml修改Config.lockWatchdogTimeout來另行指定
    另外Redisson還通過加鎖的方法提供了leaseTime的參數(shù)來指定加鎖的時間。超過這個時間后鎖便自動解開了。
    
// 加鎖以后10秒鐘自動解鎖
// 無需調用unlock方法手動解鎖
lock.lock(10, TimeUnit.SECONDS);

// 嘗試加鎖,最多等待100秒,上鎖以后10秒自動解鎖
boolean res = lock.tryLock(100, 10, TimeUnit.SECONDS);
if (res) {
   try {
     ...
   } finally {
       lock.unlock();
   }
}
//如果我們指定了鎖的過期時間 那么在源碼中會直接幫我們創(chuàng)建一個過期時間是指定的鎖  時間到期后就會把該鎖刪除
        //如果我們沒有指定過期時間 那么在執(zhí)行的時候 首先會創(chuàng)建一把鎖且過期時間是30秒  然后會創(chuàng)建異步任務  每隔10秒 去執(zhí)行任務來續(xù)期
        //實際開發(fā)中 我們最好指定過期時間---》性能考慮--》計算代碼的執(zhí)行時間
        myLock.lock(10, TimeUnit.SECONDS);//過期時間是10s  業(yè)務時間超過10s 會不會自動續(xù)期
        try {
            System.out.println("加鎖成功...業(yè)務處理....." + Thread.currentThread().getName());
            Thread.sleep(30000);
        }catch (Exception e){
        
        }finally {
            System.out.println("釋放鎖成功..." +  Thread.currentThread().getName());
            // 釋放鎖
            myLock.unlock();
        }
        return "hello";
    }
公平鎖(Fair Lock)保證了當多個Redisson客戶端線程同時請求加鎖時,優(yōu)先分配給先發(fā)出請求的線程。所有請求線程會在一個隊列中排隊,當某個線程出現(xiàn)宕機時,
Redisson會等待5秒后繼續(xù)下一個線程,也就是說如果前面有5個線程都處于等待狀態(tài),那么后面的線程會等待至少25秒。

RLock fairLock = redisson.getFairLock("anyLock");
// 最常見的使用方法
fairLock.lock();

大家都知道,如果負責儲存這個分布式鎖的Redis節(jié)點宕機以后,而且這個鎖正好處于鎖住的狀態(tài)時,這個鎖會出現(xiàn)鎖死的狀態(tài)。為了避免這種情況的發(fā)生,Redisson內部提供了一個監(jiān)控鎖的看門狗,它的作用是在Redisson實例被關閉前,不斷的延長鎖的有效期。默認情況下,看門狗的檢查鎖的超時時間是30秒鐘,也可以通過修改Config.lockWatchdogTimeout來另行指定。

另外Redisson還通過加鎖的方法提供了leaseTime的參數(shù)來指定加鎖的時間。超過這個時間后鎖便自動解開了。


// 10秒鐘以后自動解鎖
// 無需調用unlock方法手動解鎖
fairLock.lock(10, TimeUnit.SECONDS);

// 嘗試加鎖,最多等待100秒,上鎖以后10秒自動解鎖
boolean res = fairLock.tryLock(100, 10, TimeUnit.SECONDS);
...
fairLock.unlock();
讀寫鎖(ReadWriteLock)分布式可重入讀寫鎖允許同時有多個讀鎖和一個寫鎖處于加鎖狀態(tài)。
RReadWriteLock rwlock = redisson.getReadWriteLock("anyRWLock");
// 最常見的使用方法
rwlock.readLock().lock();
// 或
rwlock.writeLock().lock();

大家都知道,如果負責儲存這個分布式鎖的Redis節(jié)點宕機以后,而且這個鎖正好處于鎖住的狀態(tài)時,這個鎖會出現(xiàn)鎖死的狀態(tài)。為了避免這種情況的發(fā)生,Redisson內部提供了一個監(jiān)控鎖的看門狗,它的作用是在Redisson實例被關閉前,不斷的延長鎖的有效期。默認情況下,看門狗的檢查鎖的超時時間是30秒鐘,也可以通過修改Config.lockWatchdogTimeout來另行指定。

另外Redisson還通過加鎖的方法提供了leaseTime的參數(shù)來指定加鎖的時間。超過這個時間后鎖便自動解開了。

// 10秒鐘以后自動解鎖
// 無需調用unlock方法手動解鎖
rwlock.readLock().lock(10, TimeUnit.SECONDS);
// 或
rwlock.writeLock().lock(10, TimeUnit.SECONDS);

// 嘗試加鎖,最多等待100秒,上鎖以后10秒自動解鎖
boolean res = rwlock.readLock().tryLock(100, 10, TimeUnit.SECONDS);
// 或
boolean res = rwlock.writeLock().tryLock(100, 10, TimeUnit.SECONDS);
...
lock.unlock();
-------------------------------------------------------------
根據業(yè)務操作我們可以分為讀寫操作,讀操作其實不會影響數(shù)據,那么如果還對讀操作做串行處理,效率會很低,這時我們可以通過讀寫鎖來解決這個問題
在讀寫鎖中,只有讀讀的行為是共享鎖,相互之間不影響,只要有寫的行為存在,那么就是一個互斥鎖(排他鎖)
---------------------------------------------------------------------------------------------
   @GetMapping("/write")
    @ResponseBody
    public String writeValue(){
        RReadWriteLock readWriteLock = redissonClient.getReadWriteLock("rw-lock");
        //加寫鎖
        RLock rLock = readWriteLock.writeLock();
        String s=null;
        rLock.lock();
        try {
            System.out.println("寫鎖成功");
             s = UUID.randomUUID().toString();
             stringRedisTemplate.opsForValue().set("msg", s);
            Thread.sleep(30000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            rLock.unlock();
        }
    return s;
    
    }
    
    /**
     * 讀讀操作 相當于沒有加鎖
     * 寫 讀操作  需要等待寫鎖釋放 讀鎖才能讀取  阻塞
     * 寫 寫  阻塞方式
     * 讀寫  讀數(shù)據的時候也會添加鎖  那么寫的行為也會阻塞
     * @return
     */
    @GetMapping("/read")
    @ResponseBody
    public String readValue(){
        RReadWriteLock readWriteLock = redissonClient.getReadWriteLock("rw-lock");
        //加讀鎖
        RLock rLock = readWriteLock.readLock();
        rLock.lock();
        String s = null;
        try {
            System.out.println("讀鎖成功");
            s = stringRedisTemplate.opsForValue().get("msg");
            Thread.sleep(30000);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
        //    rLock.unlock();
        }
        return s;
    
    }
    

?

閉鎖
基于Redisson的Redisson分布式閉鎖

  @ResponseBody
    @GetMapping("/lockDoor")
    public String lockDoor() {
        RCountDownLatch door = redissonClient.getCountDownLatch("door");//阻塞 等待count 等于0 時才能繼續(xù)執(zhí)行
        door.trySetCount(5);
        try {
            door.await();//阻塞等待5個執(zhí)行完
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return "關門熄燈";
    }
    
    @GetMapping("/goHome/{id}")
    @ResponseBody
    public String goHome(@PathVariable  Long id){
        RCountDownLatch door = redissonClient.getCountDownLatch("door");
        door.countDown();
    
        return id+"下班走人";
    }
信號量(Semaphore)
基于Redis的Redisson的分布式信號量    限流
@GetMapping("/park")
    @ResponseBody
    public String park(){
        RSemaphore park = redissonClient.getSemaphore("park");
        boolean b = true;
        try {
            // park.acquire(); // 獲取信號 阻塞到獲取成功
            b = park.tryAcquire();// 返回獲取成功還是失敗
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "停車是否成功:" + b;
    }

    @GetMapping("/release")
    @ResponseBody
    public String release(){
        RSemaphore park = redissonClient.getSemaphore("park");
        park.release();
        return "釋放了一個車位";
    }

?

本文摘自 :https://www.cnblogs.com/

開通會員,享受整站包年服務立即開通 >