Redisson的基本使用

一、概述

Redisson是一个在Redis的基础上实现的Java驻内存数据网格(In-Memory Data Grid)。它不仅提供了一系列的分布式的Java常用对象,还提供了许多分布式服务。Redisson提供了使用Redis的最简单和最便捷的方法。Redisson的宗旨是促进使用者对Redis的关注分离,从而让使用者能够将精力更集中地放在处理业务逻辑上。

Redisson和jedis以及lettuce一样都是redis客户端,只不过Redisson功能更强大。

官方文档:https://github.com/redisson/redisson/wiki/%E7%9B%AE%E5%BD%95

二、Redisson的使用

2.1 搭建环境

① 引入redssion坐标依赖:

<!-- 以后使用redisson作为所有分布式锁,分布式对象等功能框架-->
<dependency>
    <groupId>org.redisson</groupId>
    <artifactId>redisson</artifactId>
    <version>3.12.0</version>
</dependency>

② 配置redisson,程序化的配置方法是通过构建Config对象实例来实现的:

复制代码
@Configuration
public class MyRedissonConfig {

    //注册RedissonClient对象
    @Bean(destroyMethod="shutdown")
    RedissonClient redisson() throws IOException {
        Config config = new Config();
        config.useSingleServer().setAddress("redis://192.168.182.150:6379");
        RedissonClient redissonClient = Redisson.create(config);
        return redissonClient;
    }
}
复制代码

2.2 可重入锁(Reentrant Lock)

复制代码
@ResponseBody
@GetMapping("/hello")
public String hello(){
    //获取一把锁
    RLock lock = redissonClient.getLock("my-lock");

    //加锁
    lock.lock();
    //锁的自动续期,如果业务执行时间超长,运行期间会自动给锁续期30秒时间,不用担心业务时间长,锁自动过期
    //加锁的业务只要运行完成,就不会给当前锁续期,即使不手动解锁,锁默认在30秒后也会自动删除
    try {
        System.out.println("加锁成功,执行业务.... "+Thread.currentThread().getId());
        Thread.sleep(30000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    } finally {
        //手动解锁
        System.out.println("解锁..."+Thread.currentThread().getId());
        lock.unlock();
    }
    return "hello";
}
复制代码

如果负责储存这个分布式锁的Redisson节点宕机以后,而且这个锁正好处于锁住的状态时,这个锁会出现锁死的状态。为了避免这种情况的发生,Redisson内部提供了一个监控锁的看门狗,它的作用是在Redisson实例被关闭前,不断的延长锁的有效期。默认情况下,看门狗的检查锁的超时时间是30秒钟,也可以通过修改Config.lockWatchdogTimeout来另行指定。

另外Redisson还通过加锁的方法提供了leaseTime的参数来指定加锁的时间。超过这个时间后锁便自动解开了。

复制代码
@ResponseBody
@GetMapping("/hello")
public String hello(){
    //获取一把锁
    RLock lock = redissonClient.getLock("my-lock");
    // 加锁
    // 设置的自动解锁时间一定要大于业务执行时间,因为在锁时间到了以后,不会自动续期
    lock.lock(10, TimeUnit.SECONDS);
    try {
        System.out.println("加锁成功,执行业务.... "+Thread.currentThread().getId());
        Thread.sleep(30000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    } finally {
        //解锁
        System.out.println("解锁..."+Thread.currentThread().getId());
        lock.unlock();
    }
    return "hello";
}
复制代码

结论:

  • lock.lock()即没有指定锁的过期时间,就是用30s,即看门狗的默认时间,只要占锁成功,就会启动一个定时任务【重新给锁设置过期时间,新的过期时间就是看门狗的默认时间】,每隔10秒就会自动续期到30秒。
  • lock.lock(10, TimeUnit.SECONDS),默认锁的过期时间就是我们指定的时间。

2.3 读写锁

基于Redis的Redisson分布式可重入读写锁RReadWriteLock Java对象实现了java.util.concurrent.locks.ReadWriteLock接口。其中读锁和写锁都继承了RLock接口。

分布式可重入读写锁允许同时有多个读锁和一个写锁处于加锁状态。

① 读锁

复制代码
@GetMapping("/read")
public String readValue(){
    RReadWriteLock lock = redissonClient.getReadWriteLock("rw-lock");
    String s = "";
    //加读锁
    RLock rLock = lock.readLock();
    rLock.lock();
    try {
        System.out.println("读锁加锁成功"+Thread.currentThread().getId());
        s = redisTemplate.opsForValue().get("writeValue");
        Thread.sleep(30000);
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        rLock.unlock();
        System.out.println("读锁释放"+Thread.currentThread().getId());
    }
    return  s;
}
复制代码

② 写锁

复制代码
@GetMapping("/write")
public String writeValue(){
    // 获取一把锁
    RReadWriteLock lock = redissonClient.getReadWriteLock("rw-lock");
    String s = "";
    // 加写锁
    RLock rLock = lock.writeLock();
    try {
        //1、改数据加写锁,读数据加读锁
        rLock.lock();
        System.out.println("写锁加锁成功..."+Thread.currentThread().getId());
        s = UUID.randomUUID().toString();
        Thread.sleep(30000);
        redisTemplate.opsForValue().set("writeValue",s);
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        rLock.unlock();
        System.out.println("写锁释放"+Thread.currentThread().getId());
    }
    return  s;
}
复制代码

测试:

先加写锁,后加读锁,此时并不会立刻给数据加读锁,而是需要等待写锁释放后,才能加读锁
先加读锁,再加写锁:有读锁,写锁需要等待
先加读锁,再加读锁:并发读锁相当于无锁模式,会同时加锁成功
总结:只要有写锁的存在,都必须等待,写锁是一个排他锁,只能有一个写锁存在,读锁是一个共享锁,可以有多个读锁同时存在。
  

2.4 信号量(Semaphore)

基于RedisRedisson的分布式信号量(SemaphoreJava对象RSemaphore采用了与java.util.concurrent.Semaphore相似的接口和用法

复制代码
RSemaphore semaphore = redisson.getSemaphore("semaphore");
semaphore.acquire();
//
semaphore.acquireAsync();
semaphore.acquire(23);
semaphore.tryAcquire();
//
semaphore.tryAcquireAsync();
semaphore.tryAcquire(23, TimeUnit.SECONDS);
//
semaphore.tryAcquireAsync(23, TimeUnit.SECONDS);
semaphore.release(10);
semaphore.release();
//
semaphore.releaseAsync();
复制代码

2.5 闭锁(CountDownLatch)

基于RedissonRedisson分布式闭锁(CountDownLatchJava对象RCountDownLatch采用了与java.util.concurrent.CountDownLatch相似的接口和用法。

RCountDownLatch latch = redisson.getCountDownLatch("anyCountDownLatch");
latch.trySetCount(1);
latch.await();

// 在其他线程或其他JVM里
RCountDownLatch latch = redisson.getCountDownLatch("anyCountDownLatch");
latch.countDown();

 

https://blog.csdn.net/qq_38697437/article/details/121359818

posted @   wq9  阅读(3637)  评论(0编辑  收藏  举报
(评论功能已被禁用)
编辑推荐:
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)
点击右上角即可分享
微信分享提示