Redisson分布式锁、可重入锁

介绍Redisson

什么是 Redisson?来自于官网上的描述内容如下!

Redisson 是一个在 Redis 的基础上实现的 Java 驻内存数据网格客户端(In-Memory Data Grid)。它不仅提供了一系列的 redis 常用数据结构命令服务,还提供了许多分布式服务,例如分布式锁、分布式对象、分布式集合、分布式远程服务、分布式调度任务服务等等。

相比于 Jedis、Lettuce 等基于 redis 命令封装的客户端,Redisson 提供的功能更加高端和抽象

配置Redisson

引入依赖

java 复制代码
        <dependency>
            <groupId>org.redisson</groupId>
            <artifactId>redisson</artifactId>
            <version>3.13.6</version>
        </dependency>

配置客户端类

java 复制代码
@Configuration
public class RedisConfig {

    @Bean
    public RedissonClient redissonClient(){
        Config config = new Config();
        //添加了单机redis地址,也可以使用useClusterServers()添加集群地址
        config.useSingleServer().setAddress("redis://192.168.2.129:6379").setPassword("linux02");
        return Redisson.create(config);
    }
}

使用Redisson分布式锁

java 复制代码
Long id = UserHolder.getUser().getId();
        
        RLock redisLock = redissonClient.getLock("lock:order:" + id);
        
        //尝试获取锁
        boolean tryLock = redisLock.tryLock();

        //判断锁是否获取成功
        if (!tryLock){
            return Result.fail("不允许重复下单");
        }

        try {
            //锁加到这里,事务提交后才释放锁
            //获取事务的动态代理对象,需要在启动类加注解暴漏出对象
            IVoucherOrderService proxy = (IVoucherOrderService)AopContext.currentProxy();//拿到动态代理对象
            return proxy.createVoucherOrder(voucherId, voucher);
            //使用动态代理类的对象,事务可以生效
        } finally {
            redisLock.unlock();
        }

不可重入锁

在同一个线程中,method1获取锁后,调用method2,method2中尝试获取锁,此时锁已经被method1获取,则method2获取锁失败,这就是不可重入锁,前面实现的锁就是不可重入锁!

Redisson可重入锁

可重入锁,从字面来理解,就是可以重复进入的锁,也叫做递归锁,指的是同一线程外层函数获得锁之后,内层递归函数仍然有获取该锁的代码,但不受影响。

ReentrantLocksynchronized都是可重入锁。

在一个类中,如果synchronized方法1调用了synchronized方法2,方法2是可以正常执行的,这说明synchronized是可重入锁。否则,在执行方法2想获取锁的时候,该锁已经在执行方法1时获取了,那么方法2将永远得不到执行。

为了实现可重入锁,**redis中使用hash类型不再使用string类型,****为什么要使用hash类型,**就不得不说到Redisson可重入锁在redis中的实现原理:

实现原理 :

在同一线程中,method1成功获取锁后调用method2,method2也尝试获取锁,此时要先判断method2所在线程和method1所在线程是否是同一线程,若是,则method2也获取锁成功,它和method1显然获取了同一个锁****,那么该锁被获取次数+1,而这个锁被获取的次数我们需要记录,也就是说value不仅要记录 线程名 还要记录 锁被获取的次数,那么我们就由此采用hash类型更合理!

为什么记录锁被获取的次数?

一个业务的完成可能要多次获取锁,如一个业务中执行了method1,method1调用了method2,method2调用了method3,这三个方法都加同一个锁(可重入锁),当method3执行完后,并不能立刻释放method3的锁,而是锁被获取的次数-1因为锁是共享的,此时method1和method2还没执行完不能释放锁,那么什么时候释放锁?当然是锁被获取的次数减为0了,说明此时已经没有方法获取锁,那么可以安全的释放可重入锁了。

So 锁被获取的次数就是我们判断是否要释放锁的依据!

相关推荐
IT龟苓膏1 小时前
Redis 数据类型底层原理:SDS、quicklist、intset、skiplist、Bitmap、HyperLogLog 一篇讲清
数据库·redis·skiplist
dllxhcjla4 小时前
Redis
数据库·redis·缓存
牛油果子哥q9 小时前
【Redis分布式高阶篇】Redis分布式锁底层精讲:从裸锁缺陷到Redisson源码级落地,解决超时释放、锁失效、主从漏洞、锁续约难题
数据库·redis·分布式
2601_957888569 小时前
分布式新媒体架构:短视频矩阵系统的技术痛点、算法规则与效率优化实践
分布式·架构·媒体
闪电悠米10 小时前
黑马点评-Redisson-02_reentrant_lock
java·spring boot·redis·分布式·缓存
SilentSamsara11 小时前
缓存策略实战:Redis + Python 多级缓存设计与失效策略
开发语言·redis·python·缓存·性能优化
2601_9578848411 小时前
分布式媒体矩阵系统的任务调度架构:高并发分发队列与背压控制控制实践
分布式·矩阵·媒体
西安邮电大学11 小时前
Redis四大经典缓存问题
java·redis·后端·其他·面试
超梦dasgg11 小时前
Redisson解锁失败,WatchDog会不会一直续期下去?
java·redis
cheems952711 小时前
[Redis] redis常见命令和String字符串解析
数据库·redis·缓存